Reputation: 17689
I have some code that essentially looks like this:
let foos = ['foo', 'foo', 'foo'];
let bars = foos.map(foo => new Promise(resolve => resolve(foo + ' processed')));
function f(foo, bar) { '...' };
As you can see, f()
requires a foo
and a bar
argument. The problem is that bar
is a Promise
. Had f()
only required bar
, I would do:
Promise.all(bars).then(values => values.map(f));
However, f()
requires both the bar
value resulting from the Promise
and its matching non-promise foo
, so I'm not sure what's the best way to code this?
Upvotes: 1
Views: 124
Reputation: 816790
.map
passes the index of the element to the callback too, so you could do
Promise.all(bars).then(
values => values.map((value, i) => f(foos[i], value))
);
Upvotes: 3
Reputation: 19288
If foos
is not in scope of the Promise.all().then()
handler, then you need to ensure that foos
as well as bars
are delivered down the promise chain.
Here's a couple of approaches :
1. Deliver an array of objects
Each object will contain a foo
and its corresponding bar
.
let foos = ['foo', 'foo', 'foo'];
let promises = foos.map(foo => new Promise(resolve => resolve({
unprocessed: foo,
processed: foo + ' processed'
})));
// ...
Promise.all(promises).then(results => results.map(obj => f(obj.unprocessed, obj.processed)));
2. Deliver an object of arrays
The object will contain a foos
array and a congruant bars
array.
let foos = ['foo', 'foo', 'foo'];
let promise = Promise.all(foos.map(foo => new Promise(resolve => resolve(foo + ' processed'))))
.then(bars => ({ 'unprocessed': foos, 'processed': bars }));
// ...
promise.then(obj => obj.unprocessed.map((foo, i) => f(foo, obj.processed[i])));
(1) is arguably less messy than (2).
Upvotes: 1
Reputation: 42490
(Adhering to the restriction mentioned in comments that foos
is not in scope...)
You can pass the extra argument down the chain a little smoother using ES6 destructuring:
let foos = ['foo', 'foo', 'foo'];
let bars = foos.map(foo => new Promise(res => res([foo, foo + ' processed'])));
Promise.all(bars).then(values => values.map(([foo, bar]) => f(foo, bar)));
Upvotes: 0