Ivan
Ivan

Reputation: 1851

Running for loop in "parallel" using async/await promises

I currently have a for loop like this:

async myFunc() {
    for (l of myList) {
        let res1 = await func1(l)
        if (res1 == undefined) continue

        let res2 = await func2(res1)
        if (res2 == undefined) continue

        if (res2 > 5) {
            ... and so on
        }
    }
}

The thing is that func1, func2 are network calls which return promises, and I don't want them to block my for loop while waiting for them. So I don't mind working in parallel with myList[0] and myList[1], nor do I care about the order in which the items of the list are processed.

How can I achieve this?

Upvotes: 2

Views: 3383

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074545

I'd do it by writing a function that handles the one value that you're handling sequentially:

async function doOne(l) {
    let res1 = await func1(l);
    if (res1 == undefined) {
        return /*appropriate value*/;
    }

    let res2 = await func2(res1);
    if (res2 == undefined) {
        return /*appropriate value*/;
    }

    if (res2 > 5) {
        // ... and so on
    }
}

Then I'd use Promise.all with map to start all of those and let them run in parallel, getting the results as an array (if you need the results):

function myFunc() {
    return Promise.all(myList.map(doOne)); // Assumes `doOne` is written expecting to be called via `map` (e.g., won't try to use the other arguments `map` gives it)
    // return Promise.all(myList.map(l => doOne(l))); // If we shouldn't make that assumption
}

If myList is (or may be) a non-array iterable, use Array.from to get an array to use map on:

function myFunc() {
    return Promise.all(Array.from(myList.map(doOne)));
}

(Or use a for-of loop pushing to an array.)

If you don't want a failure to handle one entry in the list to prevent seeing the results from handling others in the list, use Promise.allSettled rather than Promise.all. (Note that they'll all be started either way, the only difference is whether you see the successful results when at least one of them fails.)

Upvotes: 5

Related Questions