Async-Await
异步编程的最高境界,就是根本不用关心它异步。
async 函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案。
async-await 与 promise 的关系
不存在谁替代谁,因为 async-await 是寄生于 Promise。Generator 的语法糖。
async :声明一个方法是异步的
await :可以认为是 async wait 的简写,等待一个异步方法执行完成。
基本语法
1 | async function demo(params){ |
async 函数返回的是一个 Promise 对象
必须了解的 AsyncFunction console.log(async function(){}.constructor)
在 Chrome 里申明这样一个函数,可以在控制台看到返回的其实就是一个 Promise 对象。
扩展需要了解的就是 Chrome 现在也支持 AsyncFunction , 可以在 Chrome 控制台测试:
1 | console.log(async function(){}.constructor) |
规则
- async 表示这是一个 async 函数,await 只能用在这个函数里面。
- await 表示在这里等待 Promise 对象返回结果后,在继续执行。
- await 后面跟着的应该是一个 Promise 对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了)
1 | async function demo() { |
应用
Promise 虽然一方面解决了 callback
的回调地狱,但是相对的把回调“纵向发展”了,形成了一个回调链。
1 | function sleep(wait) { |
错误处理
既然 .then(...)
不用写了,那么 .catch(...)
也不用写,可以直接用标准的 try catch
语法捕捉错误。
1 | let p = new Promise((resolve,reject)=>{ |
这是基本的错误处理,但是当内部出现错一些错误时,和上面Promise有点类似,demo() 函数不会报错,函数需要catch回调捕捉吗,这就是内部错误被‘静默’处理了。
1 | let p = new Promise((resolve,reject) => { |
注意你的并行执行和循环
如果这你想异步发出AJAX请求,使用 await 代码会同步执行,所以 async/await 需要谨慎使用。
await in for 循环:await 的执行上下文必须是 async 函数
现在有一些 .forEach
或者 .map
的循环里,比如在 .forEach
里使用 await , 这时候的上下文就变成了 Array ,而不是 async function
,就会报错。这时候你就要想到是什么错误。