anArray
.filter(x => x % 2) // odd only
.reduce(
(chain, x) => chain.then(() => networkCall(x)), // network call using an odd
Promise.resolve()
)
.then(() => console.log('all done')) // all calls complete
Sure.
Line 1: anArray
is a variable representing the array, or [1,2,3,4,5]
.
Line 2: a call to filter which uses the remainder operator to transform the (create a new) array into an array containing only odd values.
Line 3: Starts a reduce call. This is given 2 arguments consisting of the following 2 lines. The purpose of reduce is to loop over the array (now only odd numbers), and produce a single value as a result. That value can be anything. Here, it'll be a promise.
Line 4: The reduce callback which gets called for each value in the array returned by the previous filter() call. The first argument , chain
, is the accumulator which is the object representing the final result (or, really, the previous result, though it's the same in this case) with the second argument, x
, being the current element of the array we're iterating over, so 1, 3, and 5, in that order. The value of chain
is a promise that was returned by the previous iteration which, in this iteration we're adding a then() to which means after that promise is done, we're doing this other thing. Here, that other thing is calling networkCall(x)
which is a stand-in function for whatever "make a Network call to an API" means. Since then() returns a promise, that promise then becomes chain
in the next iteration of the loop. This means each network call gets added as a then() to the previous network call so that it has to wait for it to complete before it runs itself.
Line 5: This is an empty promise used as the start value for chain
. So when the first iteration of the loop happens, chain
is an empty promise that resolves right away allowing the first networkCall(x)
to happen more or less right away. In the end, what this ends up as is:
Promise.resolve() // <- initial chain value
.then(() => networkCall(1))
.then(() => networkCall(3))
.then(() => networkCall(5))
which runs in sequence resulting in a single promise that resolves when networkCall(5)
resolves. And that brings us to...
Line 7: Since reduce() is returning a promise, we can use that promise to know when all the network requests have been complete and, in this example, log the message "all done"... assuming there were no errors which we didn't account for :-o