nodejs - связывание асинхронных зависимых операций - PullRequest
0 голосов
/ 19 октября 2019

У меня есть две асинхронные операции, так что при вызове второй операции используются входные данные с выхода первой. Похоже, что для реализации таких вызовов с async и await это не будет слишком отличаться от обратных вызовов.

Учитывайте это.

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.

Второй цикл должен повторяться на основе значения, переданного первым циклом. В demo0 и demo1 второй цикл получает NaN, потому что они запускаются одновременно. Только в demo2 второй цикл получает правильное значение. Можно было бы добиться этого поведения и с помощью обратных вызовов.

Есть ли способ async/await для достижения этого поведения?

1 Ответ

3 голосов
/ 19 октября 2019

Каждый вызов функции async дает вам Обещание взамен, но Обещания не могут (разумно) добавляться к номерам, поэтому вы получаете NaN взамен.

Если вы хотитечтобы иметь возможность использовать результат Обещания, вы должны await it и использовать полученное выражение . Если вы await Обещание и затем попытаетесь использовать исходное Обещание, у вас останется Обещание, а не значение, поэтому вам следует присвоить await ed Обещание переменной, например, изменить

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

(вы не можете позвонить второму loop, пока не будет I0, потому что второму loop нужно число с разрешением I0 Обещание. Либо так, либо передайте Обещание I1, и I1 правильно потребите его с .then или await)

и

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()
})()
...