异步回调嵌套
JavaScript中存在异步操作,对其有依赖的动作需在回调函数中处理。如下示例,要执行待加载脚本中的函数,需要等待脚本加载完成后在回调函数中进行。如果多个异步操作逐一依赖,会形成层层嵌套的回调函数,即“回调地狱”。
Promise对象
ES6原生提供Promise对象,将异步操作以同步操作的流程表达出来,避免回调函数的层层嵌套。Promise对象代表一个异步操作,有三种状态:初始pending、成功fulfilled或失败rejected。只有异步操作的结果,可以决定初始状态变为成功或失败最终态。传给new Promise的控制函数会立即被自动调用,此函数接受两个参数resolve和reject,分别会在Promise对象状态变为成功或失败时被执行。
Promise处理链
promise.then会返回一个promise,可以用它调用下一个then。当then中的控制函数返回一个值时,它会变成当前promise的result,下一个处理程序会使用这个返回值运行。
如果then中的控制函数返回的值是一个promise,那么直到它结束之前,下一步执行会一直被暂停。在结束之后,该promise的结果会传递给下一个then中的处理程序。
把代码分割成几个可复用的函数。使用catch来处理Promise链中的所有错误,如果上面任一promise被reject,那么catch中的错误处理程序便会执行。除了明确的rejected失败状态,catch也适用于throw new Error和包括代码错误在内的任何错误。
Promise静态方法
Promise类中有4个静态方法。
Promise.resolve根据给定的value值返回resolved promise。
用来将已有的值“封装”进promise,确保接口统一性。
Promise.reject创建带有error的rejected promise。
Promise.all并行运行多个promise,并等待所有promise准备就绪。
Promise.all使用下面这样的容错机制。catch会对异常promise产生error并返回,根据promise工作原理,只要then/catch处理器返回了值,执行流程就会“正常”进行。
Promise.race与Promise.all类似,但不会等待所有promise都完成,只等待第一个promise完成后即继续执行。
async/await
ES8标准引入的async函数使得异步操作变得更加方便。
将async关键字放在函数前,意味着该函数总是会返回promise。如果代码return非promise值,会自动将其封装到resolved promise中。
await只在async函数中工作,作用是等待promise,直到其解决并返回其结果。这样的语法比promise.then更优雅地获取结果,也更容易阅读和编写。
当await的promise失败reject时,它会抛出error,就像该行上有常规throw语句一样,可以使用try…catch来捕获这个error。
参考:
http://es6.ruanyifeng.com/#docs/promise
http://es6.ruanyifeng.com/#docs/async
https://javascript.info/async