理解 Async 和 Await
本文最初发表于https://maximorlov.com/understanding-async-await/
学习 async/await 可能会让人望而生畏。你可能已经拖延了几周甚至几个月了!
您可能知道同步代码和异步代码之间的区别,但您却完全不知道如何应用它。
照这样下去,很难想象你将如何理解异步JavaScript。😫
但学习 async/await 并不一定很可怕!
只需一些指导和正确的方法,你就能编写出可以正常工作的现代异步代码。不是下个月,也不是下周,而是今天。
确实,async/await 一开始是不直观的......但这只是因为你还没有为它建立一个心理模型!
要理解 async/await,我们首先要了解一下 Promise。由于 async/await 建立在 Promise 之上,因此当你编写 async/await 时,你实际上是在处理底层的 Promise。
什么是Promise
?
简单来说,aPromise
是一个代表未来值的 JavaScript 对象。它包含两条信息:promise状态,以及一个值或错误(取决于状态)。
承诺可以处于以下状态之一:
- pending — 初始状态,操作正在进行中
- fulfilled — 操作成功完成
- 拒绝— 操作失败
当 Promise 已完成或已拒绝,但未处于待处理状态时,该 Promise 即被结算。Promise 最终会以某个值完成,或因错误(或原因)而拒绝。
返回承诺的函数根据定义是异步函数。(记住这一点,我们稍后会回顾)
尽管承诺是同步返回的,但承诺里面的值是异步的,只有在承诺履行后才能访问。
究竟起什么作用await
?
当您在承诺前面添加 await 关键字时,您指示 JavaScript 运行时暂停当前函数内的执行,等到承诺解决,并且只有在承诺解决后,才继续执行该函数内的其余代码。
Await保证您在特定时间点之后仍可以访问异步值。在 Promise 执行完成并返回该值(或因错误而拒绝)之前,运行时不会执行函数内的任何其他代码。
需要记住的一点是,启动异步操作和等待其结果是两个独立的操作。当你将它们写在不同的行上时,这一点会变得清晰。
因此,await 仅负责暂停后续执行,直到异步操作完成。它并不是启动异步操作的机制。
怎么样async
?
该async
关键字赋予函数特殊的能力。
标记为 async 的函数可以在其函数体内的任何位置暂停执行。换句话说,该函数可以使用 await 关键字。await 只能在async 函数内部使用。(稍后您就会明白为什么)
异步函数有两个重要属性:
- 它总是返回一个 Promise
- 您可以在其范围内使用 await 关键字
当你在异步函数中返回非Promise 值时,该值会被包装在 Promise 中然后返回。
async function getFive() {
return 5;
}
console.log(getFive()); // Promise { ... }
还记得我之前说过的关于返回 Promise 的函数吗——它们本质上就是异步的。因此,标记为 async 的函数始终是异步的。
返回 Promise 的非async
函数也是异步的。以下代码实际上与上面的代码相同:
function getFive() {
return Promise.resolve(5);
}
console.log(getFive()); // Promise { ... }
所有其他功能都被视为同步功能。
为什么async
&await
密不可分
知道 await 会暂停函数内部的执行,并且如果非异步函数不返回承诺,则它是同步的,您可以开始明白为什么以下代码不起作用:
function getFive() { // function is not async
const five = await fetchFive(); // 🚫 doesn't work, can't use await
return five;
}
需要等待first ,怎么才能getFive()
同步返回呢?five
fetchFive()
换句话说,如何等待异步值然后继续同步返回它?
你根本就做不到。
这就是为什么 await 只能在用 async 关键字声明的函数中使用。async 函数将返回值包装在 Promise 中,从而使返回值异步。
希望你现在对 async/await 有了更好的理解。赶紧在你的项目中使用它吧!
将回调转换为干净的异步代码!🚀
厌倦了凌乱的回调代码?下载这份免费的五步指南,掌握 async/await 并简化你的异步代码。
只需几步,即可将复杂的逻辑转换为易于维护、可读性强的现代 JavaScript。清晰的可视化界面将每个步骤分解,方便您轻松上手。
文章来源:https://dev.to/maximization/understanding-async-await-22o6