天天看点

从 async 和 await 函数返回值说原理

从 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 的。

学习更多技能

请点击下方公众号