- 发布时间
你必须知道的,async/await 实现异步流程控制
作者
Chad
async/await
async 其实是 ES7 才有的关键字,放在这里说,其实是和我们前面所说的 Promise、Generator 有很大关联的。async 的意思是"异步",顾名思义是和异步操作有关的关键字。而且 async/await 是 Generator 中 yield 的语法糖。
具体参考 阮老师的 ES6 入门。
我们这里就展示一下 async/await 的实际作用。
async
const helloFn = async () => {
return "helloAsync"
}
console.log(helloFn) //Promise {<resolved>: "helloAsync"}
可以看到,经过 async 包装后的函数返回一个 Promise 对象。
既然是返回的 Promise 对象,我们就用 then 方法来处理。
const helloFn = async () => {
return "helloAsync"
}
helloFn().then(s => {
console.log(s) //helloAsync
})
是不是很简单?就是一个 Promise 而已,它是如何实现异步控制的呢?
await
在 Generator 中,yield 关键字只能使用在 Generator 函数中。同样,await 关键字也不能单独使用,需要使用在 async 方法中。await 字面意思是"等待",那它是在等什么呢?它是在等待后面表达式的执行结果。
- 请看下面这段示例代码,我们用定时器来模拟异步的情况
function testAwait() {
return new Promise(resolve => {
setTimeout(function() {
console.log("testAwait")
resolve()
}, 1000)
})
}
async function helloAsync() {
await testAwait()
console.log("helloAsync")
}
helloAsync()
//testAwait
//helloAsync
我们来分析下这段代码:
testAwait()方法中 new 一个 Promise 对象返回,Promise 对象中用 setTimeout 模拟一个异步过程,即 1s 后打印 "testAwait"。helloAsync()方法中,await testAwait()表示将阻塞在这里,等待 testAwait 这个异步方法执行并返回结果后,才继续下面的代码。
执行一下,1s 后打印了下面的日志:
testAwait
helloAsync
到此,是不是理解了 await 的作用?就是阻塞主函数的执行,直到后面的 Promise 函数返回结果。
await 后面只能是 Promise 对象么?答案是否定的 -- 可以是字符串、布尔值、数值以及普通函数。
function testAwait() {
setTimeout(function() {
console.log("testAwait")
}, 1000)
}
async function helloAsync() {
await testAwait()
console.log("helloAsync")
}
helloAsync()
- 得到的 结果是
helloAsynctestAwait
方法没有报错,说明 await 后面是支持非 Promise 函数的,但执行的结果是不一样的。await 针对所跟的表达式不同,有两种处理方式:
对于 Promise 对象,await 会阻塞主函数的执行,等待 Promise 对象 resolve,然后得到 resolve 的值作为 await 表达式的运算结果,再继续执行主函数接下来的代码。
对于非 Promise 对象,await 等待函数或者直接量的返回,而不是等待其执行结果。
小栗子
const aa = (resolve, reject) =>
new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1)
resolve("ok")
}, 2000)
})
const bb = () =>
new Promise((resolve, reject) => {
setTimeout(() => {
console.log(2)
resolve("ok")
}, 1000)
})
const cc = () =>
new Promise((resolve, reject) => {
setTimeout(() => {
console.log(3)
resolve("ok")
}, 500)
})
const mm = async () => {
await aa().then(s => {
console.log(s)
})
await bb().then(s => {
console.log(s)
})
await cc().then(s => {
console.log(s)
})
}
mm()
这个例子我们可以看出,三个定时器的时间依次是 2000ms、1000ms、500ms,如果不安顺序执行会先输出 3、2、1。但我们想要对它们做异步控制,按 1、2、3 执行:
- 首先把每个异步过程封装成 Promise 对象。
- 利用 await 阻塞原理,实现按顺序执行。
Support
赞赏
如果这些内容对你有所帮助,欢迎赞赏支持。