Javascript 异步函数在等待嵌套承诺实现时从不返回

Javascript 异步函数在等待嵌套承诺实现时从不返回,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,在下面的代码中,有一个外部功能和一个内部功能外部应该等待内部完成后返回internal返回一个承诺,该承诺在超时后履行。我希望outer函数在履行此承诺后立即返回: const outer = async () => { let counter = 0; const inner = async () => { console.log('inner'); return new Promise((fulfill, reject) =>

在下面的代码中,有一个
外部
功能和一个
内部
功能<代码>外部应该等待
内部
完成后返回
internal
返回一个
承诺
,该承诺在超时后履行。我希望
outer
函数在履行此
承诺后立即返回:

const outer = async () => {
    let counter = 0;
    const inner = async () => {
        console.log('inner');
        return new Promise((fulfill, reject) => {
            if (++counter === 3) {
                console.log('fulfill');
                fulfill();
                return;
            }
            setTimeout(() => inner(), 1000);
        });
    };
    return await inner();
};
outer().then(() => console.log('outer done'));
outer
永远不会完成。请注意,没有
外部完成
输出:

inner
inner
inner
fulfill
在以下代码中,外部
完成。它返回一个
承诺
本身,并且
内部
函数实现它:

const outer = async () => {
    return new Promise((fulfill, reject) => {
        let counter = 0;
        const inner = async () => {
            console.log('inner');
            if (++counter === 3) {
                console.log('fulfill');
                fulfill();
                return;
            }
            setTimeout(() => inner(), 1000);
        };
        inner().catch(err => reject(err));
    });
};
outer().then(() => console.log('outer done'));
输出:

inner
inner
inner
fulfill
outer done

我认为这两种情况下的行为应该相似。有人能看到并解释这种差异吗?

您从未在
内部调用过
fullfill
函数。你创造了一堆新的承诺,你只告诉最后一个承诺它已经解决了

让我们看看您的异步任务:

{
    if (++counter === 3) {
        console.log('fulfill');
        fulfill();
        return;
    }
    setTimeout(() => inner(), 1000);
}
在第一次调用
内部
时,即此部分:

return await inner();
计数器
位于0。这意味着整个
if
块未执行。在代码的其余部分,它从未调用
fulfill
函数,因此承诺从未得到解决

如果此代码(或此类型的代码)存在于您的生产代码库中,我的建议是您应该重写它

要快速修复它,您可能可以执行以下操作:

setTimeout(() => inner().then(() => fulfill()), 1000);

在这种情况下,您如何解释
fulfill
log的存在?这证明代码达到了这一点。@YuryFedorov您实现了上一个承诺,但不要忘记您已经创建了四个新承诺。日志实际上证明它没有到达,因为应该有4行而不是1行。