JS Promise 扫盲兼快速上手「aync/await」

663 阅读3分钟

「这是我参与11月更文挑战的第 12 天,活动详情查看:2021最后一次更文挑战

这是我为 Promise 系列精心准备的文章

JS Promise 扫盲兼快速上手「上」 - 掘金 (juejin.cn)

JS Promise 扫盲兼快速上手「中」 - 掘金 (juejin.cn)

JS Promise 扫盲兼快速上手「下」 - 掘金 (juejin.cn)

优化示例

我们现有 Promise 来做异步的回调处理,但是需要套用一个处理的模版:回调的函数不得不在 then 函数中进行处理

在 ES8 新增的特性里,aync/await 可以让我以同步的方式来编写异步的代码。举个例子,一个 Promise 执行后返回一个值 n,我们需要使用这个返回值来做回调,代码如下:

let p = new Promise((resolve, reject) => {
    fetch(url).then(d=>resolve(d));
}).then(data => do(data))

如果我们使用异步函数来编写,代码就可以变成如下:

let p = await fetch(url);

上面展示了使用 await 优化 Promise 后的效果。现在,来详细的聊聊他们的细节

async

定义异步函数

在常规的函数声明模式中,添加在 function 关键字的前面,示例:

async function test(){}

这样,就声明了 test 是一个异步函数

使用

异步函数就和普通的函数使用方法一致,直接调用即可

test()

test 调用之后,内部的函数代码块正常执行,例如

async function test(){
    console.log(2)
}
console.log(1)
test()
console.log(3)
// -> 1, 2, 3

但是,如果 test 中涉及到了异步的操作,比如,经典的 setTimeout 调用,则会将异步部分的调用压入微任务队列,其余正常执行,这里的执行逻辑,和普通的函数毫无区别!!!

但是,如果我们需要等待,setTimeout(代表异步函数) 执行完成之后,获取到返回值再继续操作,就需要为 setTimeout 这个异步函数添加 await 关键字约束,然后 test 的执行将会先挂起,等待外部的同步代码执行完成之后,再回过头来继续,演示代码:

image.png

这份代码里嵌入了 async, await, promise, setTimeout 等,他的输出提示了代码的执行顺序

我们现在在这份代码的基础来,在执行 delay() 的时候,添加关键字 await,让后面的代码等待其执行结果

image.png

这样,代码的执行顺序就有了一点的变化

返回值

async 定义的异步函数,会隐式的将结果包装为一个 Prmise.resolve 对象进行返回

image.png

如果异步函数中出现异常,比如使用 throw 关键字抛出异常,那么函数就会返回一个 Promise.reject 对象

await

表示等待一个异步函数的返回值,并且可以对 Promise 对象进行解包的操作

let a = Promise.resolve(1) 会得到一个 Promise 对象,但是我们在 Promise 前面加上 await 关键字,那么可以直接得到其值

let a = await Promise.resolve(1);
console.log(a)
// -> 1

原创文章,未经允许,禁止转载

-- by 安逸的咸鱼