How can I use reduce in the place of map when using Promise.all? My attempt results in an error UnhandledPromiseRejectionWarning: TypeError: #<Promise> is not iterable at Function.all (<anonymous>)
Eventually I would like to conditionally add innerResult to memo but I need to use reduce first.
const _ = require('lodash');
const eq = [{id:1}, {id:2}, {id:3}];
// block to replace
var biggerEq = _.map(eq, async (e) => {
const innerResult = await wait(e.id);
return innerResult;
})
// attempt at replacing above block
// var biggerEq = _.reduce(eq, async (memo, e) => {
// const innerResult = await wait(e.id);
// memo.push(innerResult)
// return memo;
// }, []);
Promise.all(biggerEq).then((result) => {
console.log(result) // outputs [ 2, 4, 6 ]
})
function wait (id) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(id * 2);
}, 1000);
})
}
If you want to replace it with reduce
, it's possible, but the logic will be a bit convoluted. Make the accumulator a Promise that resolves to an array that you can push
to, then return it so the next iteration can use it (as a Promise):
const eq = [{id:1}, {id:2}, {id:3}];
function wait (id) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(id * 2);
}, 1000);
})
}
const biggerEq = _.reduce(eq, async (arrProm, obj) => {
const [arr, innerResult] = await Promise.all([arrProm, wait(obj.id)]);
arr.push(innerResult);
return arr;
}, Promise.resolve([]));
biggerEq.then((arr) => {
console.log(arr);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
(but .map
is really more appropriate when you want to transform one array into another)