异步与回调的异同点

tech2024-09-26  22

一、什么是同步和异步?

同步:直接能拿到结果异步:不能直接拿到结果

在JS中,有的函数不能立刻拿到结果,需要等一会才能拿到结果,比如发送HTTP请求,等待响应需要一段时间。

如果 JS 不能直接拿到一个函数的结果,可以先去执行别的代码,等结果到了再取结果,这就是异步

异步的好处是可以把用来等待的时间拿去做别的事情

 

怎么判断一个函数的结果是同步的还是异步的呢?

如果一个函数的返回值在setTimeout, AJAX, AddEventListener 这三个东西内部,那么这个函数就是异步函数

二、什么是回调?

 

我们希望能够拿到异步函数的结果,有两种方法:轮询和回调

轮询就是我定时去询问拿到结果了没回调就是我写一个函数fn,然后传给异步函数,当异步函数执行完毕时,就会调用fn, 于是我们就通过回调拿到了异步处理的结果

满足以下条件的函数就是回调函数:我写给别人用,自己不用的函数

举例:

我写了函数A,传给函数B, B会调用函数A, 那么A就是回调 arr.forEach((item)=>console.log(item))(item)=>console.log(item) 这个箭头函数就是一个回调 有的时候回调还可以传给一个对象, 当我们写AJAX请求时,我们把回调传给 request.onreadystatechange,等待浏览器来调用

图中标黄的函数就是回调函数

 

 

注意:回调可以用于同步任务,不一定非要用于异步任务

 

回调举例

function 摇骰子(){ setTimeout(()=>{ return parseInt(Math.random()*6) + 1 },1000) }

 

注意在这个代码里,

摇骰子()没有写return ,即 return undefined,

箭头函数里有return, 返回真正的结果,所以这是一个异步函数

const n = 摇骰子() console.log(n)// n是Undefined

那么我们应该怎么去拿到setTimeout的结果呢?

可以用回调

function callback(x) { console.log(x) } 摇骰子(callback){ setTimeout(()=>{ callback(parseInt(Math.random()*6) + 1) },1000) }

我们可以把callback函数简化成箭头函数

摇骰子(x=>{ console.log(x) }) // 由于这里函数的参数和需要用到的值是一样的,所以还可以简化为 摇骰子(console.log)

但是如果参数个数不一样,就不能这么简化,

举例:

const array = ['1', '2', '3'].map(parseInt) 得到的结果是 [1, NaN, NaN]

这里错误的原因就是因为 忽略了Map函数和parseInt函数参数不同

首先我们来复习一下map函数

let new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])

map的回调函数有三个参数,分别是currentValue, index, array本身

而parseInt有两个参数string和 radix,表示将一个字符串string 转换为radix 进制的整数

parseInt(string, radix) 将一个字符串string 转换为radix 进制的整数

 

const array = ['1', '2', '3'].map(parseInt) 这种写法等价于 ['1', '2', '3'].map((currentValue, index, array) => { parseInt(currentValue, index, array) // parseInt('1', 0) 把'1'换成0进制,那就是1 // parseInt('2', 1) 把'2'换成1进制,1进制里没有2,所以是NaN // parseInt('3', 2) 把'3'换成2进制,2进制里没有3,所以是NaN })

下面是正确的写法,就是写明参数即可

['1', '2', '3'].map((currentValue, index, array) => { parseInt(currentValue) }

三、总结

我们来总结一下异步与回调的关系

异步任务不能拿到结果于是我们传一个回调给异步任务异步任务完成时调用回调函数调用的时候把结果作为参数

 

 

最新回复(0)