JS异步编程原型
如果能直接拿到结果就是同步
如果不能直接拿到结果就是异步
异步
以AJAX为例
-
request.send()
之后,并不能直接得到 response - 必须等到 readyState 变为 4 后,浏览器回头调用
request.onreadystatechange
- 函数 我们才能得到
request.response
回调callback
写给别人用的函数就是回调
代码举例:
function f1() {}
function f2(fn) {
fn();
}
f2(f1);//f2调用了f1
f1就是回调
异步和回调的关系
关联
- 异步任务需要在得到结果时通知 JS 来拿结果
- 怎么通知呢?
- 可以让 JS 留一个函数地址给浏览器
- 异步任务完成时浏览器调用该函数地址即可
- 同时把结果作为参数传给该函数
- 这个函数是我写给浏览器调用的,所以是回调函数
区别
- 异步任务需要用到回调函数来通知结果
- 但回调函数不一定只用在异步任务里
- 回调可以用到同步任务里
-
array.forEach( n => console.log(n) )
就是同步回调
如何判断是否是异步
如果一个函数的返回值处于setTimeout
、AJAX(即XMLHttpRequest
)、addEventListener
这三个的内部,那么这个函数就是异步函数
举个例子:
//摇骰子例子
function 摇骰子() {
setTimeout(() => {
//箭头函数
return parseInt(Math.random() * 6) + 1; //随机1~6的整数
}, 1000);
//return undefined
}
摇骰子()没有return 所以返回undefined,箭头函数有返回值,返回真正的结果
所以这是一个异步函数
//摇骰子例子续
const n = 摇骰子();
console.log(n); // undefined
//如何能拿到异步结果呢?使用回调
摇骰子((x) => {
console.log(x);
});//x就是我们要的点数,把这个函数传给摇骰子()
//可以简化为「摇骰子(console.log)」参数一致才能简化
function 摇骰子(fn) {
setTimeout(() => {
// 箭头函数
fn(parseInt(Math.random() * 6) + 1);
}, 1000);
}
小结
- 异步任务不能拿到结果
- 于是我们传一个回调给异步任务
- 异步任务完成时调用回调
- 调用的时候把结果作为参数