JS中的async与await异步编程及await使用陷阱
作者:尘世冒险家
ECMA2017中新加入了两个关键字async与await
简单来说它们是基于promise之上的的语法糖,可以让异步操作更加地简单明了
首先我们需要用async关键字,将函数标记为异步函数
async function f() { } f()
异步函数就是指:返回值为promise对象的函数
比如之前用到的fetch()就是一个异步函数,返回的是promise
在异步函数中,我们可以调用其他的异步函数,不过我们不再需要使用then,而是使用一个await。
await会等待Promise完成之后直接返回最终结果
所以这里的response已经是一个服务器返回的响应数据了
async function f() { const response = await fetch("http://....") } f()
虽然await看上去会暂停函数的执行,但在等待的过程中,js同样可以处理其他的任务
这是因为await底层是基于promise与事件循环(event loop)机制实现的
await使用时的陷阱:
1、第一个陷阱
比如:我们分别去await这两个异步操作
async function f() { const a = fetch("http://..../post/1") const b = fetch("http://..../post/2") } f()
虽然不存在逻辑错误
但这样会打破这两个fetch()操作的并行
因为我们会等到第一个任务执行完成之后才开始执行第二个任务
这里更高效的方法是将所有的Promise用Promise.all组合起来,然后再去await:
修改之后的执行效率会直接提升一倍
async function f() { const promiseA = fetch("http://..../post/1") const promiseB = fetch("http://..../post/2") const [a, b] = await Promise.all([promiseA,promiseB]) } f()
2、第二个陷阱
如果我们需要在循环中执行异步操作,是不能够直接调用forEach或者map这一类方法的,尽管我们在回调函数中写了await也不行。
因为这里的forEach会立即返回,它并不会等到所有的异步操作都执行完毕
async function f() { [1,2,3].forEach(async (i) => { await someAsyncOperation(); }) console.log("done") } f()
如果我们希望等待循环中的异步操作都一一完成之后才继续执行
我们应当使用传统的for循环
async function f() { for( let i of [1,2,3]){ await someAsyncOperation(); } console.log("done") } f()
如果我们希望所有的程序并发执行,一种更炫酷的写法就是使用for await
这里的for循环依然会等到所有的异步操作都完成之后才会继续向后执行
3、第三个陷阱
我们不能在全局或者普通函数中直接使用await关键字
await只能用在异步函数(async function)中
如果我们想要在最外层中使用await,那么需要先定义一个异步函数:
使用await async可以让我们写出更清晰,更容易理解的异步代码
到此这篇关于async与await异步编程的文章就介绍到这了,更多相关async与await异步编程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!