非同步概念的最後一小块拼图,要来学习怎麽使用 async/await
async/await 是 ECMAScript 2017 引入的语法糖,对於遇到非同步脑袋就打结的我,async/await 简直就是救星~
async/await 像个连体婴一样总是形影不离,不过它们长得还是不一样嘛,所以还是先分开认识一下
如果在一般函式前加上 async 关键字,代表我们宣告了一个非同步函式
先来看看一般函式,和在同一个函式前加上 async 的区别
可以观察到只要在函式前加上 async,就保证这个函式会回传一个 Promise
,即使函式的回传值只是单纯的字串或数字,也会自动用 Promise 包裹起来
await 会放在非同步函式前,他的作用是等待非同步函式执行完成并回传结果,不需要像 Promise 得使用.then() 取得 resolve 的值。
//非同步函式,等待两秒後回传顾客点的饮料
function makeDrinks(drinks) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(drinks);
}, 2000);
});
}
async function sellDrinks() {
const firstOrder = await makeDrinks("black tea");
console.log(firstOrder);
}
sellDrinks(); // black tea
// 在一般函式内使用 await 会报错
function sellDrinks() {
const firstOrder = await makeDrinks("black tea");
console.log(firstOrder);
}
sellDrinks();
//SyntaxError: await is only valid in async function
对关键字有基础认识後,用一个简单的范例理解 async/await 的执行步骤
async function foo() {
const result = await new Promise((resolve) => setTimeout(() => resolve('1'), 1000))
console.log(result)
}
foo();
// 一秒过後,印出1
理解执行的顺序後,应该就不难理解下述的例子为什麽执行时间会是4秒
function makeDrinks(drinks) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(drinks);
}, 2000);
});
}
async function sellDrinks() {
console.time();
const firstOrder = await makeDrinks("black tea");
const secondOrder = await makeDrinks("bubble tea");
console.log(`Here is your ${firstOrder}`);
console.log(`Here is your ${secondOrder}`);
console.timeEnd();
}
// Here is your black tea
// Here is your bubble tea
// default: 4.023s
下面两个例子的执行时间大约都是两秒左右,但 MDN 并不建议第一种做法,如果希望非同步函式同时执行的话,建议使用Promise.all()
或Promise.allSettled()
// 写法1
async function sellDrinks() {
console.time();
const order = makeDrinks("black tea");
const extraOrder = makeDrinks("bubble tea");
const totalOrder = (await order) + "," + (await extraOrder);
console.log(`Here is your ${totalOrder}`);
console.timeEnd();
}
sellDrinks();
// Here is your black tea,bubble tea
// default: 2.029s
//写法2
async function sellDrinks() {
console.time();
const totalOrder = await Promise.all([
makeDrinks("black tea"),
makeDrinks("bubble tea"),
]);
console.log(`Here is your ${totalOrder[0]}`);
console.log(`Here is your ${totalOrder[1]}`);
console.timeEnd();
}
sellDrinks();
// Here is your black tea
// Here is your bubble tea
// default: 2.031s
使用了 async/await 後,不仅写非同步感觉像在写同步,在错误处理方面也可以用熟悉的try...catch语法。
之前看着学姊用 async/await 觉得好羡慕啊,写起来轻松又好读,但自己要写却不知从何写起,现在回头想想大概是因为当时尚未理解非同步的整个脉络。
慢慢从 callback 循序理解 Promise 的使用,再尝试将 Promise 替换成 async/await 後,对於 Promise 又再理解了一些些。
参考资料:
MDN
JAVASCRIPT.INFO
Asynchronous 非同步进化顺序 - Async/Await
<<: Python GUI - 要如何在画面上显示右键选单呢?
>>: Day 22 | 状态管理套件 MobX - 基本使用
"什麽叫你只会加密128位元?" --- 花了不少篇幅介绍两中区块加密方式,DE...
找到股价站上 20 周线只是第一步,不是一站上就会开始飙升,我还会搭配价位突破「箱型区间」,这个突破...
终於到最後一天啦! 在嘉实工作 5 年多来,虽然一直知道公司发展的 XS 是国内程序交易的先驱者,...
昨天把整个专案架起来了 今天我们就可以开始来刻画面了 这边也要提一下之前我们其实是直接开写 先从会员...
今天的实作要透过一个计算BMI的小程序来使用AsyncTask类别,在这之中,我们要加入Thread...