赶快承诺拒绝

phi*_*hag 12 javascript node.js promise async-await es6-promise

如何在以后检索承诺的结果?在测试中,我在发送进一步请求之前检索电子邮件:

const email = await get_email();
assert.equal(email.subject, 'foobar');
await send_request1();
await send_request2();
Run Code Online (Sandbox Code Playgroud)

如何在慢速邮件检索过程中发送请求?

起初,我考虑过稍后等待电子邮件:

// This code is wrong - do not copy!
const email_promise = get_email();
await send_request1();
await send_request2();
const email = await email_promise;
assert.equal(email.subject, 'foobar');
Run Code Online (Sandbox Code Playgroud)

如果get_email()成功,这可以工作,但如果get_email()在相应的之前失败则失败await,并且完全合理UnhandledPromiseRejectionWarning.

当然,我可以使用Promise.all,像这样:

await Promise.all([
    async () => {
        const email = await get_email();
        assert.equal(email.subject, 'foobar');
    },
    async () => {
        await send_request1();
        await send_request2();
    },
]);
Run Code Online (Sandbox Code Playgroud)

然而,它使代码更难阅读(它看起来更像是基于回调的编程),尤其是在以后的请求实际上依赖于电子邮件,或者有一些嵌套回事.是否可以在以后存储承诺的结果/例外await

如果需要,这里有一个带有模拟的测试用例,有时会失败并且有时可以使用随机时间.它绝不能输出UnhandledPromiseRejectionWarning.

pon*_*tek 6

const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const send_request1 = () => wait(300), send_request2 = () => wait(200);
async function get_email() {
    await wait(Math.random() * 1000);
    if (Math.random() > 0.5) throw new Error('failure');
    return {subject: 'foobar'};
}

const assert = require('assert');
async function main() {
    // catch possible error
    const email_promise = get_email().catch(e => e);
    await send_request1();
    await send_request2();
    // wait for result
    const email = await email_promise;
    // rethrow eventual error or do whatever you want with it
    if(email instanceof Error) {
      throw email;
    }
    assert.equal(email.subject, 'foobar');
};

(async () => {
    try {
        await main();
    } catch(e) {
        console.log('main error: ' + e.stack);
    }
})();
Run Code Online (Sandbox Code Playgroud)