起因:
我们的js的异步是使用回调进行实现,而它有几个缺点
从回调函数->promise->promise+generrator = async/await
回调函数
1缺乏可信度
控制反转,使回调函数给别人使用,当回调函数执行过早,过晚,多次调用等问题时,会出现bug,所以不可信任
2回调嵌套(回调地狱)
promise
后面我们使用promise来进行解决,以then操作的形式,进行链式操作,而不再是回调地狱
promise的缺点
1promise一旦新建就会立即执行,无法中途取消
但是我们思考到了几种方式来中断promise请求
1.1promsie.race方法
1.2promise中抛出异常,被catch方法捕捉
1.3Promises/A+标准:原Promise对象的状态将跟新对象保持一致。利用这一特性,当新对象保持“pending”状态时,原Promise链将会中止执行。
Promise.resolve().then(() => {
console.log('ok1')
return new Promise(()=>{}) // 返回“pending”状态的Promise对象
}).then(() => {
// 后续的函数不会被调用
console.log('ok2')
}).catch(err => {
console.log('err->', err)
})
2promsie异常捕捉,只能被catch捕捉,当不写catch的时候,会被promise内部吞掉
拓展:
try…catch异常捕捉,只能捕捉同步方法,因为异步方法执行的时候,已经不再try…catch内部。已经脱离了try…catch的执行栈和上下文
3当处于pending状态时,无法得知当前处于哪一个状态,是刚刚开始还是刚刚结束
4 如果 Promise 连续调用,对于错误的处理是很麻烦的。你无法知道错误出在哪里。因为最后只有一个兜底的catch操作
const makeRequest = () => {
return callAPromise()
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => {
throw new Error("oops");
})
}
generator+promise = async/await
而我们的generator(生成器)实则就是一个打断点执行的操作。通过next,yield进行一步步的操作
后来我们发现可以吧generator和promise进行结合实现完美的promise操作。后面就是有我们的async/await操作
优点:
1以同步的方式进行书写,而不是then.then.then的回调操作,增强可读性。
2对同步更加的友好,例如调用promise1,使用promise1返回的结果去调用promise2,然后使用两者的结果去调用promise3。
3对同步错误捕获更加的友好,try-catch可以捕获async/await的错误
4解决不知道错误才哪里的问题,解决promise缺点4
5调试更加的简单,友好
推荐书籍:你不知道的javascript中,第三章promise
资料