原文:Async and Await in JavaScript Explained by Making Pizza,作者:Dave Gray
async 和 await 可能听起来很复杂……但是一旦你深入了解它们,它们就像比萨饼一样简单。
我们都在日常生活中使用 async 和 await。
什么是异步任务
异步任务可让你在完成一个任务的同时完成其他任务。
以下是一些日常异步任务示例
示例 1:
你在驾车时订购食物,这会启动你的食物请求(异步任务)。
在准备食物的同时,你在保持向前(下一个任务)。
你不必等待食物准备好就可以前进。
你正在等待食物,你的要求在取货窗口得到满足。
示例 2:
你在厨房拖地。当你等待厨房地板干燥时,可以用吸尘器清理卧室的地毯。
最初的任务是清洁你的厨房地板,当地板干燥时,任务就完成了。
站在原地等待地板干燥的效率并不高,因此你在等待厨房地板干燥的同时用吸尘器清理卧室地板。
这也是 Javascript 处理异步函数的方式。
Async/Await 示例——烤冷冻比萨
你决定在烤箱中烤披萨,第一步是预热烤箱。因此,你设置了所需的温度并开始预热烤箱。
当烤箱预热时,你将冷冻披萨从冰箱中取出,打开盒子,然后将其放在披萨盘上。
你还有时间!
也许在等待烤箱准备好时发出哔哔声的同时,你可以喝一杯饮料并看一些电视节目。
下面是一些代码来模拟这个例子:
// 这个 async 函数模拟烤箱响应
const ovenReady = async () => {
return new Promise(resolve => setTimeout(() => {
resolve('Beep! Oven preheated!')
}, 3000));
}
// 定义 preheatOven async 函数
const preheatOven = async () => {
console.log('Preheating oven.');
const response = await ovenReady();
console.log(response);
}
// 定义其他函数
const getFrozenPizza = () => console.log('Getting pizza.');
const openFrozenPizza = () => console.log('Opening pizza.');
const getPizzaPan = () => console.log('Getting pan.');
const placeFrozenPizzaOnPan = () => console.log('Putting pizza on pan.');
const grabABeverage = () => console.log('Grabbing a beverage.');
const watchTV = () => console.log('Watching television.');
// 调用函数
preheatOven();
getFrozenPizza();
openFrozenPizza();
getPizzaPan();
placeFrozenPizzaOnPan();
grabABeverage();
watchTV();
// 在控制台按顺序输出:
Preheating oven.
Getting pizza.
Opening pizza.
Getting pan.
Putting pizza on pan.
Grabbing a beverage.
Watching television.
Beep! Oven preheated!
上面的过程正是 async 和 await 的全部内容。
当我们等待(await
)异步 preheatOven
函数完成时,我们可以执行同步任务,如 getFrozenPizza
、openFrozenPizza
、getPizzaPan
、placeFrozenPizzaOnPan
、grabABeverage
,甚至 watchTV
。
我们就是这样执行异步任务的
这也是异步 Javascript 的工作原理。
请注意,当我们 await
来自 async
函数的响应时,需要在另一个 async
函数中调用它。这就是我们在上面看到的,在 preheatOven
内部调用 ovenReady
。
要记住的两个关键点:
- Javascript 不会等待像
preheatOven
这样的异步函数完成,然后才会继续执行getFrozenPizza
和openFrozenPizza
等后续任务。 - 在继续执行父异步函数中的下一个任务之前,Javascript 将等待(
await
)像ovenReady
这样的async
函数完成并返回数据。当console.log(response)
语句在ovenReady
返回响应之后才执行时,我们会看到这一点。
我知道日常示例对我们中的一些人有帮助,但其他人可能更喜欢真正的代码。
因此,我将在下面提供一个不太抽象的 async 和 await JavaScript 示例,该示例使用 Fetch API 请求数据:
JavaScript 中的 Async/Await 示例
const getTheData = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw Error();
const data = await response.json();
// 用这些数据做点什么……保存到数据库,更新 DOM 等。
console.log(data);
console.log('You will see this last.')
} catch (err) {
console.error(err);
}
}
getTheData();
console.log('You will see this first.');
总结
我希望我已经帮助你理解了 JavaScript 中的 async 和 await。
我知道要完全掌握可能需要一段时间。开始为你想要的披萨预热烤箱,并在等待哔哔声的同时查看更多 async 和 await 示例吧!
下面是我发布在 Youtube 频道的教程。该视频提供了更深入的解释和更多代码示例,包括对回调、promises、thenables、Fetch API 以及 async 和 await 的讨论: