同步与异步
异步:
- AJAX是异步的,request.sent() 后不能直接得到 response,必须等到 readyState 变为4后, 浏览器回头调用request.onreadystatechange 函数才能得到 request.response
- 轮询
- 回调 callback: 写了却不调用,给别人调用的函数,就是回调(让别人回头调用一下)
function f1(){}
function f2(fn){
fn()
}
f2(f1) // f1 就是回调
异步与回调的关系:
- 异步任务需要用回调函数来通知结果,步骤为:
- JS留一个函数地址给浏览器
- 异步任务完成时浏览器调用该函数地址
- 同时把结果作为参数传给该函数
- 回调函数不一定只在异步任务里,也可以用到同步任务里
array.forEach(n => console.log(n))
就是同步回调
判断异步同步
- 异步:一个函数的返回值处于
setTimeOut
、AJAX
、AddEventListener
内部,就是异步函数
总结:
- 异步任务不能直接拿到结果
- 于是我们传一个回调给异步任务
- 异步任务完成时调用回调
- 调用时把结果作为参数
promise
- 异步任务有两个结果:成功或失败
- 回调三个问题:
- 命名不规范
- 回调地狱
- 不方便捕获错误
- 为了解决以上三个问题,使用 promiss(1976年提出的思想)
使用 promise 封装 ajax
ajax = (method, url) => {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open(method, url);
request.onreadystatechange = () => {
if (request.readyState === 4) {
// 成功调用 resolve, 失败调用 reject
if (request.status < 400) {
resolve.call(null, request.response);
}else if(request.status >= 400) {
reject.call(null, request);
}
}
}
request.send();
})
}
ajax('GET', './xxx').then(success, fail);
- 创建 promiss : return new Promise ((resolve, reject) => {})
Promise.prototype.then:返回一个 Promise,接收两个参数,Promise 的成功和失败情况的回调函数
Promise.prototype.then(value => {
// fulfillment
}, reason => {
// rejection
});
Promise.all:提供了并行执行异步操作的能力,在所有异步操作执行完后才执行回调, 会把所有异步操作的结果放进一个数组中传给 then
Promise.all(iterable);
Promise.race:用法与 all 一样,只不过 all 是等所有异步操作都执行完毕后才执行 then 回调。而 race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调
Promise.race(iterable);
promise 库:axios, jQuery.ajax