【问题标题】:nodejs - Chaining dependent asynchrous operationsnodejs - 链接依赖的异步操作
【发布时间】:2020-02-16 01:25:39
【问题描述】:

我有两个异步操作,因此第二个操作的调用使用第一个输出的输入。用asyncawait 实现这样的调用,看起来与回调并没有太大的不同。

考虑一下。

async function loop(label, I) {
    console.log('%s - Looping for %d times.', label, I)
    console.time(label)
    for (i = 0; i < I; ++i) {
    }
    return Promise.resolve(I)
}
//
async function demo0() {
    // Refer - https://stackoverflow.com/a/45479579/919480
    let I0 = loop('01', 10)
    let I1 = loop('02', I0 * 1000)
    await I0
    await I1
}
//
async function demo1() {
    // Refer - https://stackoverflow.com/a/45479579/919480
    let I0 = loop('11', 10)
    await I0
    let I1 = loop('12', I0 * 1000)
    await I1
}
//
async function demo2() {
    await loop('21', 10).then(async (i) => {
        await loop('22', i * 1000)
    })
}
//
(async () => {
    await demo0()
    await demo1()
    await demo2()
})()

结果:

01 - Looping for 10 times.
02 - Looping for NaN times.
11 - Looping for 10 times.
12 - Looping for NaN times.
21 - Looping for 10 times.
22 - Looping for 10000 times.

第二个循环应该基于第一个循环传递的值进行迭代。在demo0demo1 中,第二个循环收到NaN,因为它们是同时触发的。只有在demo2 中,第二个循环才会收到正确的值。也可以通过回调实现这一行为。

有没有async/await 方法来实现这种行为?

【问题讨论】:

    标签: javascript node.js asynchronous async-await


    【解决方案1】:

    async 函数的每次调用都会给你一个 Promise 作为回报,但 Promise 不能(明智地)添加到数字中,所以你会得到 NaN 作为回报。

    如果您希望能够使用 Promise 的结果,您应该 await并使用结果表达式。如果你await Promise 然后尝试使用原始 Promise,你仍然会有一个 Promise,而不是一个值,所以你应该将 awaited Promise 分配给一个变量,例如更改

    let I0 = loop('01', 10)
    let I1 = loop('02', I0 * 1000)
    await I0
    await I1
    

    let I0 = loop('01', 10)
    const resolveValueI0 = await I0;
    let I1 = loop('02', resolveValueI0 * 1000)
    await I1
    

    (在完成I0 之前,您不能调用第二个loop,因为第二个loop 需要来自I0 的Promise 的分辨率的数字。要么那个,要么将 Promise 传递给 I1,并让 I1 正确使用 .thenawait)

    let I0 = loop('11', 10)
    await I0
    let I1 = loop('12', I0 * 1000)
    await I1
    

    let I0 = loop('11', 10)
    const resolveValueI0 = await I0;
    let I1 = loop('12', resolveValueI0 * 1000)
    await I1
    

    async function loop(label, I) {
        console.log('%s - Looping for %d times.', label, I)
        console.time(label)
        for (i = 0; i < I; ++i) {
        }
        return Promise.resolve(I)
    }
    //
    async function demo0() {
        // Refer - https://stackoverflow.com/a/45479579/919480
        let I0 = await loop('01', 10)
        let I1 = loop('02', I0 * 1000)
        await I0
        await I1
    }
    //
    async function demo1() {
        // Refer - https://stackoverflow.com/a/45479579/919480
        let I0 = loop('11', 10)
        const result = await I0
        let I1 = loop('12', result * 1000)
        await I1
    }
    //
    async function demo2() {
        await loop('21', 10).then(async (i) => {
            await loop('22', i * 1000)
        })
    }
    //
    (async () => {
        await demo0()
        await demo1()
        await demo2()
    })()

    【讨论】:

    • 嗯...是的,我错过了关于Promise 分辨率的那个。不过,这也是另一种选择,对吧? let I0 = await loop('01', 10); let I1 = await loop('02', I0 * 1000).
    • 是的,这实际上是首选选项,只要它不会让您感到困惑 - 减少不必要的变量通常是一件好事。
    猜你喜欢
    • 1970-01-01
    • 2020-10-30
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多