首页 > 解决方案 > 为什么我可以等待此代码但不能使用 .then?

问题描述

Node.JS 10.15,无服务器,lambda,本地调用

样品 A)这工作:

export async function main(event) {
    const marketName = marketIdToNameMap[event.marketId];
    const marketObject = marketDirectory[marketName];
    const marketClient = await marketObject.fetchClient();

    const marketTime = await marketObject.getTime(marketClient);
    console.log(marketTime);
}

样品 B) 这有效:

export function main(event) {
    const marketName = marketIdToNameMap[event.marketId];
    const marketObject = marketDirectory[marketName];

    marketObject.fetchClient().then((marketClient)=>{
        marketObject.getTime(marketClient).then((result) => {
            console.log('<---------------> marker 1 <--------------->');
            console.log(result);
        });
    });
}

样品 C) 但这不是:

export async function main(event) {
    const marketName = marketIdToNameMap[event.marketId];
    const marketObject = marketDirectory[marketName];
    const marketClient = await marketObject.fetchClient();

    console.log('<---------------> marker 1 <--------------->');

    marketObject.getTime(marketClient).then((result) => {
        console.log('<---------------> marker 22 <--------------->');
        console.log(result);
    });
}

getTime 的胆量适用于所有示例:

function getTime(marketClient){
    return new Promise((resolve, reject) => {
        return marketClient.getTime((err, result) => {
            if (err) {
                reject(err);
            }
            resolve(result);
        });
    }).catch(err => {
        throw err;
    });
}

显然,将 async/await 与经典的 promise then-ables 混合似乎是一个问题。我希望SAMPLE C 能够工作,因为 getTime() 正在返回一个承诺。但是,代码只是默默地完成,从不碰到第二个标记。我必须把第一个标记放在那里,以确保任何代码都运行。感觉我应该能够混合 async/await 和 thenables,但我不能在这里考虑什么。

@adrian,不 在此处输入图像描述

标签: javascriptnode.jsasync-awaites6-promiseserverless

解决方案


您既不等待也不返回来自 的承诺marketObject.getTime().then(),这将导致该承诺链独立执行,主函数返回并且进程关闭。记住..then也返回一个承诺。

解决方案是

await marketObject.getTime(marketClient).then(...

或者

return marketObject.getTime(marketClient).then(...

无论哪种方式,都将 Promise 链接到 main 函数,这样无论执行什么,它都会始终等待所有 Promise 解决(或拒绝)。

我怀疑示例 B 有效,因为 main 不是异步的,而 Lambda 将等待事件循环完成。即,即使 main 提前返回,它也会执行承诺链。

https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

如果您在代码中不使用回调,AWS Lambda 将隐式调用它并且返回值为 null。调用回调时, AWS Lambda 会继续调用 Lambda 函数,直到事件循环为空

...而且我怀疑如果您返回一个 Promise(就像您在示例 C 中所做的那样),那么 Lambda 将在它解决后立即终止该过程,这是因为您不等待/返回.then()链,因此浮动承诺您创建的链将不会执行。


推荐阅读