如何在不创建 Promise 的情况下将 await 与异步函数一起使用?

prs*_*s99 1 javascript async-await

我知道一个异步函数返回一个 Promise,所以我想到了替换这段代码:

const hi = function (delay) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('hi');
                resolve();
            },delay)
        });
    };

const bye = async () => {
    await hi(1000);
    await hi(1000);
    await hi(1000);
    await hi(1000);
    return 'bye';
};

bye().then((msg) => {
    console.log(msg);
});
Run Code Online (Sandbox Code Playgroud)

使用此代码:

const hi = async (delay) => {
    setTimeout(() => {
        console.log('hi');
    },delay);
};

const bye = async () => {
    await hi(1000);
    await hi(1000);
    await hi(1000);
    await hi(1000);
    return 'bye';
};

bye().then((msg) => {
    console.log(msg);
});
Run Code Online (Sandbox Code Playgroud)

唯一的区别是我使用的是异步函数而不是返回 Promise 的函数,因为异步函数返回的是 Promise。但是第二个代码也没有像我预期的那样工作。它只是 console.logs 立即再见,然后在 1 秒之后 console.logs 'hi' 4 次。你能帮我理解这背后的原因吗?

You*_*saf 5

两个代码示例中的一个主要区别与hi函数的返回值有关。

在第一个代码示例中,函数hi 返回一个承诺,而在第二个代码示例中,函数hi 没有显式返回任何值;因此,async函数返回的承诺被隐式解析为 的值,undefined而无需等待setTimeout的回调函数执行。

承诺对象不会使任何事情异步;它只是一个已经异步操作的包装器,promise 对象通知异步操作是成功完成还是失败。

在第一个代码示例中,您在setTimeout. 这种包装的诺言没有实现,直到 resolve从的回调函数中调用setTimeout

在第二个代码示例中,async函数返回的承诺不会自动绑定到函数内部的异步代码。

调用后setTimeout,代码执行到hi函数结束;由于没有明确的return声明,async函数返回的 promise以 的值实现undefined。这发生调用 的回调函数之前setTimeout