昨天在文章《JavaScript中的 async 和 await》中简单的介绍了其使用方法。那么 async 和 await 如何工作,如何正确的使用 async 和 await 。
什么是 async 和 await ?
简单来说,它们是 promise
嵌套的语法糖,来看一个实例:
async function helloAsync() { const result = await new Promise((resolve) => setTimeout(() => resolve("Hello")) ); console.log(result); // Hello } helloAsync();
运行上面的代码,函数将输出 “Hello
”,结果显而易见,其中 await
将阻塞主线程,直到 promise
处理完成。
async
async
函数使我们能够编写基于 promise
的代码,就像它是同步的一样,但不会阻塞执行线程。通过事件循环异步运行,async
函数将始终返回一个值。使用 async
简单地将返回一个 promise
,如果 apromise
没有返回,会自动将它包装在一个 promise
带有它的值的 resolve
中。
await
await
运算符用于等待 promise
,它只能在 async
块内使用。关键字 await
使 JavaScript 等待直到 promise
返回结果。
需要注意的是,它只是让
async
功能块等待,而不是整个程序执行。不能在常规函数中使用await
关键字。
猜猜下面代码片段的输出
async function helloAsync() { const result = await new Promise((resolve) => setTimeout(() => resolve("Hello")) ); return result; } let asyncResult = helloAsync(); console.log("helloAsync返回值:" + JSON.stringify(asyncResult));
根据上面的代码,可能会认为输出 “Hello
” ,对与错要眼见为实,复制上面的代码运行后,输出为:asyncResult值:{}
,从输出来看,变量 asyncResult
的值为 {}
。
为什么会这样?
因为异步函数总是返回一个承诺,而不是解决上面例子中的承诺,我们试图从中提取价值。
如何解决?
由于 async 函数在上面的代码片段中返回了一个 promise
对象,那么就可以使用 .then
方法获取 async
函数的处理结果。下面的代码可以正常打印 async
函数的执行结果。
async function helloAsync() { const result = await new Promise((resolve) => setTimeout(() => resolve("Hello")) ); return result; } helloAsync().then((data) => { console.log("helloAsync返回值:" + JSON.stringify(data)); });
更好的方法
使用 async
和 await
主要是想避免使用 promise
链或 .then
表达式,所以可以使用 async
和 await
本身来解决 promise
,而不是使用 .then
,下面代码为推荐使用方式:
async function helloAsync() { const result = await new Promise((resolve) => setTimeout(() => resolve("Hello")) ); return result; } async function testHelloAsync() { const output = await helloAsync(); console.log("helloAsync返回值:" + JSON.stringify(output)); } testHelloAsync();
总结
在实际开发项目中,是使用 Promises
还是 Async/Await
没有好坏之分,取决于开发人员,我个人当前是偏向使用 Promises
的。