Print two array one after another(with interval) in javascript - javascript

I have two array :
numbers:[1,2,3,4]
letters: ["a","b","c","d"]
I want to print as the numbers array first with time interval of 3 sec and then print letters array.
output should be: 1(3sec interval) 2(3sec interval) 3(3sec interval) 4(3sec interval) 5(3sec interval) a b c d.
I tried with following code:
const result = document.getElementById("frame")
const numbers = [1,2,3,4], letters = ["a","b","c","d"]
const function1 = () =>
letters.forEach((c, i) => setTimeout(() => console.log(c)));
const function2 = () =>
numbers.forEach((c, i) => setTimeout(() => console.log(c), i * 3000));
async function main(){
await function1();
await function2();
}
main();

const numbers = [1, 2, 3, 4]
const letters = ['a', 'b', 'c', 'd']
const wait = value => new Promise(resolve => setTimeout(() => resolve(), value))
const function1 = async () => {
numbers.forEach(async (item, i) => {
await wait(3000 * i)
console.log(item)
})
await wait(3000 * numbers.length - 1)
letters.forEach((item) => {
console.log(item)
})
}
function1()

You can do this
const numbers = [1,2,3,4], letters = ["a","b","c","d"]
const function1 = () => new Promise((resolve) => {
letters.forEach((c, i) => setTimeout(() => console.log(c), i * 3000));
setTimeout(resolve, letters.length * 3000)
})
const function2 = () =>
numbers.forEach((c, i) => setTimeout(() => console.log(c)));
async function main(){
await function1();
await function2();
}
main();

If you're just logging all the letters at once the function doesn't need to be async. You can just return the joined array from function2.
function1 does need to be async but that's not what happening in your code. Because setTimeout doesn't behave well inside async functions you need to set up a promise-based delay, and then use that inside the function.
const numbers = [1, 2, 3, 4];
const letters = ['A', 'B', 'C', 'D'];
// Resolve a promise after a given time
function delay(time) {
return new Promise(res => {
return setTimeout(() => res(), time);
});
}
function function1(arr) {
// Return a promise that is awaited
return new Promise(res => {
// Loop over the array
async function loop(i) {
// Log the element
console.log(arr[i]);
// Call the delay function
await delay(3000);
// And then work out if you need
// to call `loop` again, or resolve the promise
if (arr.length - 1 === i) {
res();
} else {
loop(++i);
}
}
// Call loop for the first time
loop(0);
});
}
function function2(arr) {
return arr.join(' ');
}
async function main() {
await function1(numbers);
console.log(function2(letters));
}
main();

For the record, another simple example where the output is awaited. This assumes your final goal of outputting will be the same for both arrays, just without delays. In case the actual output method is async, you can await that too, but keep a single entry point for both arrays
const numbers = [1,2,3,4], letters = ["a","b","c","d"];
async function output(arr,delayAfterEach){
for(element of arr){
console.log(element);
if(delayAfterEach)
await new Promise(r=>setTimeout(r,delayAfterEach));
}
}
async function main(){
await output(numbers,3000);
await output(letters);
}
main();

Related

How to wait for a loop with promises to complete to execute a method?

I want to execute a loop with promises, but I want to execute a method only after the loop completes.
This is a similar example of that I want to do
const array = ['a', 'b', 'c'];
console.log('start');
array.forEach((i) => {
setTimeout(()=> console.log(i), 3000);
});
console.log('end');
this the result i got.
start
end
a
b
c
setTimeout is asynchronous, but is not thenable like a promise. If your direct question is to execute your code when all the timeouts end, then it should be done as follows:
const array = ['a', 'b', 'c'];
let numberOfTimeoutsToBeExecuted = array.length;
// keep track of the number of timeouts that have finished execution
let numberOfTimeoutsExecuted = 0;
console.log('start');
array.forEach((i) => {
setTimeout(() => {
console.log(i),
numberOfTimeoutsExecuted += 1;
// execute your code when the last timeout has finished execution
if (numberOfTimeoutsToBeExecuted === numberOfTimeoutsExecuted) {
console.log('end');
}
}, 3000);
});
However, if you want to wait for multiple promises to finish execution, the following is the best way to do this:
const array = ['a', 'b', 'c'];
const promises = [];
console.log('start');
array.forEach((i) => {
// add all promises that will be executed into array
promises.push(new Promise((resolve, reject) => {
setTimeout(()=> {
console.log(i);
resolve();
}, 3000);
}));
});
// execute all promises here
Promise.all(promises).then(() => console.log('end'));
One option is do the following:
const array = ['a', 'b', 'c'];
console.log('start');
const promises = [];
array.forEach((i) => {
promises.push(new Promise(resolve => setTimeout(() => {
console.log(i)
resolve()
}, 3000)))
})
Promise.all(promises).then(() => {
console.log('end');
})
It's easily doable with something like Promise.all once you know how.
The key is to create an array of Promises and then call Promise.all on it.
But before I can show we need to make some adjustments:
First let's wrap setTimeout to return a promise:
function delay(amount) {
return new Promise((resolve) => {
setTimeout(resolve, amount);
});
}
Then change the code to push all created promises onto an array:
const array = ['a', 'b', 'c'];
let promises = [];
async function doSomething(i) {
console.log(i);
await delay(3000);
}
console.log('start');
array.forEach((i) => {
const promise = doSomething(i);
promises.push(promise);
});
Here doSomething is doing the asynchronous work.
Lastly, we wait for all Promises to be resolved with Promise.all:
await Promise.all(promises);
console.log('end');
Gives:
start
a
b
c
end
function delay(amount) {
return new Promise((resolve) => {
setTimeout(resolve, amount);
});
}
const array = ['a', 'b', 'c'];
let promises = [];
async function doSomething(i) {
console.log(i);
await delay(3000);
}
console.log('start');
array.forEach((i) => {
const promise = doSomething(i);
promises.push(promise);
});
Promise.all(promises).then(() => {
console.log('end');
});

How to make result of Promise all in order

Question:
the output of case1 is from 0 to 4 which is in order while
the output of case2 is in random.
I know the reason why case1's result is in order is that the request is send after the result of previous request comes.
In case2 the request will not wait the result of previous request.
my question is that is there a way to retain the result of case2 in order too?
case1
const main = async () => {
const arr = Array.of(...[1,2,3,4,5])
for (let i=0;i<arr.length;i++) {
console.log(`request:${i}`)
const res = await request(i)
console.log(res)
}
console.log("next step")
}
const request = (i:number):Promise<number> => {
return new Promise<number>(((resolve, reject) => {
setTimeout(()=>{
resolve(i)
},Math.random() * 1000)
}))
}
output1
closure
request:0
0
request:1
1
request:2
2
request:3
3
request:4
4
next step
case2
const main = async () => {
const arr = Array.of(...[1,2,3,4,5])
await Promise.all(arr.map(async (v,i) => {
console.log(`request:${v}`)
const res = await request(v)
console.log(`result:${res}`)
console.log(res)
})).catch((e) => {
})
console.log("next step")
}
const request = (i:number):Promise<number> => {
return new Promise<number>(((resolve, reject) => {
setTimeout(()=>{
resolve(i)
},Math.random() * 1000)
}))
}
main()
output2
request:1
request:2
request:3
request:4
request:5
result:4
4
result:5
5
result:1
1
result:3
3
result:2
2
next step
Promise.all() returns an array of the results in the same order; they just won't resolve in order. You could return the response within your request promise, and...
const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3]);
Or if you wanted to iterate over an array...
const results = await Promise.all([promise1, promise2, promise3]);
Promise All should be array of request or promise, in map() should return request.
try this
const main = () => {
const arr = Array.of(...[1,2,3,4,5])
Promise.all(arr.map((v,i) => {
console.log(`request:${v}`)
return request(v)
})).then((res)=>{
res.forEach((val)=>{
console.log(`result:${val}`)
})
}).catch((e) => {
})
console.log("next step")
}
const request = (i)=> {
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(i)
}, Math.floor(Math.random() * 10)*1000)
})
}
main()

Execute promises map sequentially

I have written a function that is being called in a loop (map) and that function is using promises. Now, I want that function to run synchronously and exit before its next instance is called.
function t1(){
let arr1 = [1,2,3,4,5];
return Promise.map(arr1, (val) =>{
const params = {
"param1" : val1
};
return t2(params);
});
}
function t2(event){
return Promise.resolve()
.then({
//do something
//code doesn't reach here in sync manner. all five instance are invoked and then code reaches here for first instance and so on
})
.then({
//promise chaining. do something more
})
}
t2 is beingcalled five times, but I want each instance to be called only after the instance before it has returned the value.
Currently its not behaving like that but invoking the function five times in parallel.
I can't use async/await due to project limitations.
The problem with your current code is that Promise.prototype.map, like forEach, does not wait for asynchronous functions called inside it to complete. (No asynchronous call will ever be waited for unless you tell the interpreter to do so explicitly with await or .then)
Have t1 await each call of t2:
async function t1(){
let arr1 = [1,2,3,4,5];
const results = [];
for (const val of arr1) {
results.push(await t2(val));
}
return results;
}
Or if you want to use reduce instead of async/await:
const delay = () => new Promise(res => setTimeout(res, 500));
function t1(){
let arr1 = [1,2,3,4,5];
return arr1.reduce((lastProm, val) => lastProm.then(
(resultArrSoFar) => t2(val)
.then(result => [...resultArrSoFar, result])
), Promise.resolve([]));
}
function t2(event){
return delay().then(() => {
console.log('iter');
return event;
});
}
t1()
.then(results => console.log('end t1', results));
Or, if you need the sequential functionality to be encapsulated in t2, then have t2 have a semi-persistent variable of the previous Promise it generated:
const delay = () => new Promise(res => setTimeout(res, 500));
const t1 = () => {
return Promise.all([1, 2, 3, 4].map(t2));
};
const t2 = (() => {
let lastProm = Promise.resolve();
return (event) => {
const nextProm = lastProm
.catch(() => null) // you may or may not want to catch here
.then(() => {
// do something with event
console.log('processing event');
return delay().then(() => event);
});
lastProm = nextProm;
return nextProm;
};
})();
t1().then(results => console.log('t1 done', results));
(function loop(index) {
const next = promiseArray[index];
if (!next) {
return;
}
next.then((response) => {
// do Something before next
loop(index + 1);
}).catch(e => {
console.error(e);
loop(index + 1);
});
})(0 /* startIndex */)
Here is what running Promises sequentially would look like when using .reduce() in combination with async/await:
async function main() {
const t2 = (v) => Promise.resolve(v*2)
const arr1 = [1,2,3,4,5];
const arr1_mapped = await arr1.reduce(async (allAsync, val) => {
const all = await allAsync
all.push(await t2(val) /* <-- your async transformation */)
return all
}, [])
console.log(arr1_mapped)
}
main()

Return dependent promises sequentially inside loop

I'm working on shopify integration.
We receive an array items then loop through them and add them a new model (func1) then I need to use that result from the first and add it to a schedule (func2).
I need this functions to run sequentially because I'm adding the results to a schedule and if I have two results for the same date and they don't yet exist in the database if the they run in parallel it creates 2 separate entries in the database instead of one entry with the two values.
The way I need to return is func1, func2, func1, func2....
But at the moment is returning func1, func1...func2, func2...
This is a simplified example of what I need to accomplish.
const func2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
return console.log('func2');
}, 3000);
});
};
const func1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Func1');
func2();
}, 1000);
});
};
const array = [1, 2, 3, 4, 5];
const test = () => {
array.map(x => {
func1();
});
};
test();
If there is something that isn't clear please let me know.
Thanks
you can use async/await and for loop in order do create a synced like iteration. and use it again in your func1 in order to reslove
const func2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('func2');
resolve();
}, 3000);
});
};
const func1 = () => {
return new Promise( (resolve, reject) => {
setTimeout(async () => {
console.log('Func1');
await func2();
resolve();
}, 1000);
});
};
const array = [1, 2, 3, 4, 5];
const test = async () => {
for(let i=0;i<array.length;i++){
await func1();
}
};
test();
This is the perfect place to use the traverse function:
const traverse = (xs, f) => xs.reduce((promise, x) =>
promise.then(ys => f(x).then(y => Promise.resolve(ys.concat([y])))),
Promise.resolve([]));
const times2 = x => new Promise(resolve => setTimeout(() => {
console.log("times2", x);
resolve(2 * x);
}, 1000));
const minus1 = x => new Promise(resolve => setTimeout(() => {
console.log("minus1", x);
resolve(x - 1);
}, 1000));
const xs = [1,2,3,4,5];
const ys = traverse(xs, x => times2(x).then(minus1));
ys.then(console.log); // [1,3,5,7,9]
Hope that helps.
const func2 = async (modalValue) => {
let result = modalValue*5;
console.log(`Function2 result: ${result}`)
return result;
};
async function getModalValue(i){
// rest of your Code
return { modal: i*2}
}
const func1 = async (item) => {
let {modal} = await getModalValue(item);
console.log(`Function1 modal: ${modal}`)
await func2(modal);
};
const array = [1, 2, 3, 4, 5];
const test = async () => {
for(let i=0;i<array.length;i++){
await func1(array[i]);
}
};
test().then((resp)=> {console.log("Completed")})
.catch((err)=>{console.log("failure")})

Filtering an array with a function that returns a promise

Given
let arr = [1,2,3];
function filter(num) {
return new Promise((res, rej) => {
setTimeout(() => {
if( num === 3 ) {
res(num);
} else {
rej();
}
}, 1);
});
}
function filterNums() {
return Promise.all(arr.filter(filter));
}
filterNums().then(results => {
let l = results.length;
// length should be 1, but is 3
});
The length is 3 because Promises are returned, not values. Is there a way to filter the array with a function that returns a Promise?
Note: For this example, fs.stat has been replaced with setTimeout, see https://github.com/silenceisgolden/learn-esnext/blob/array-filter-async-function/tutorials/array-filter-with-async-function.js for the specific code.
Here is a 2017 elegant solution using async/await :
Very straightforward usage:
const results = await filter(myArray, async num => {
await doAsyncStuff()
return num > 2
})
The helper function (copy this into your web page):
async function filter(arr, callback) {
const fail = Symbol()
return (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i=>i!==fail)
}
Demo:
// Async IIFE
(async function() {
const myArray = [1, 2, 3, 4, 5]
// This is exactly what you'd expect to write
const results = await filter(myArray, async num => {
await doAsyncStuff()
return num > 2
})
console.log(results)
})()
// Arbitrary asynchronous function
function doAsyncStuff() {
return Promise.resolve()
}
// The helper function
async function filter(arr, callback) {
const fail = Symbol()
return (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i=>i!==fail)
}
I'll even throw in a CodePen.
As mentioned in the comments, Array.prototype.filter is synchronous and therefore does not support Promises.
Since you can now (theoretically) subclass built-in types with ES6, you should be able to add your own asynchronous method which wraps the existing filter function:
Note: I've commented out the subclassing, because it's not supported by Babel just yet for Arrays
class AsyncArray /*extends Array*/ {
constructor(arr) {
this.data = arr; // In place of Array subclassing
}
filterAsync(predicate) {
// Take a copy of the array, it might mutate by the time we've finished
const data = Array.from(this.data);
// Transform all the elements into an array of promises using the predicate
// as the promise
return Promise.all(data.map((element, index) => predicate(element, index, data)))
// Use the result of the promises to call the underlying sync filter function
.then(result => {
return data.filter((element, index) => {
return result[index];
});
});
}
}
// Create an instance of your subclass instead
let arr = new AsyncArray([1,2,3,4,5]);
// Pass in your own predicate
arr.filterAsync(async (element) => {
return new Promise(res => {
setTimeout(() => {
res(element > 3);
}, 1);
});
}).then(result => {
console.log(result)
});
Babel REPL Demo
For typescript folk (or es6 just remove type syntax)
function mapAsync<T, U>(array: T[], callbackfn: (value: T, index: number, array: T[]) => Promise<U>): Promise<U[]> {
return Promise.all(array.map(callbackfn));
}
async function filterAsync<T>(array: T[], callbackfn: (value: T, index: number, array: T[]) => Promise<boolean>): Promise<T[]> {
const filterMap = await mapAsync(array, callbackfn);
return array.filter((value, index) => filterMap[index]);
}
es6
function mapAsync(array, callbackfn) {
return Promise.all(array.map(callbackfn));
}
async function filterAsync(array, callbackfn) {
const filterMap = await mapAsync(array, callbackfn);
return array.filter((value, index) => filterMap[index]);
}
es5
function mapAsync(array, callbackfn) {
return Promise.all(array.map(callbackfn));
}
function filterAsync(array, callbackfn) {
return mapAsync(array, callbackfn).then(filterMap => {
return array.filter((value, index) => filterMap[index]);
});
}
edit: demo
function mapAsync(array, callbackfn) {
return Promise.all(array.map(callbackfn));
}
function filterAsync(array, callbackfn) {
return mapAsync(array, callbackfn).then(filterMap => {
return array.filter((value, index) => filterMap[index]);
});
}
var arr = [1, 2, 3, 4];
function isThreeAsync(number) {
return new Promise((res, rej) => {
setTimeout(() => {
res(number === 3);
}, 1);
});
}
mapAsync(arr, isThreeAsync).then(result => {
console.log(result); // [ false, false, true, false ]
});
filterAsync(arr, isThreeAsync).then(result => {
console.log(result); // [ 3 ]
});
Here's a way:
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);
var filterAsync = (array, filter) =>
Promise.all(array.map(entry => filter(entry)))
.then(bits => array.filter(entry => bits.shift()));
filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));
The filterAsync function takes an array and a function that must either return true or false or return a promise that resolves to true or false, what you asked for (almost, I didn't overload promise rejection because I think that's a bad idea). Let me know if you have any questions about it.
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);
var filterAsync = (array, filter) =>
Promise.all(array.map(entry => filter(entry)))
.then(bits => array.filter(entry => bits.shift()));
filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));
var console = { log: msg => div.innerHTML += msg + "<br>",
error: e => console.log(e +", "+ (e.lineNumber-25)) };
<div id="div"></div>
Promise Reducer to the rescue!
[1, 2, 3, 4].reduce((op, n) => {
return op.then(filteredNs => {
return new Promise(resolve => {
setTimeout(() => {
if (n >= 3) {
console.log("Keeping", n);
resolve(filteredNs.concat(n))
} else {
console.log("Dropping", n);
resolve(filteredNs);
}
}, 1000);
});
});
}, Promise.resolve([]))
.then(filteredNs => console.log(filteredNs));
Reducers are awesome. "Reduce my problem to my goal" seems to be a pretty good strategy for anything more complex than what the simple tools will solve for you, i.e. filtering an array of things that aren't all available immediately.
asyncFilter method:
Array.prototype.asyncFilter = async function(f){
var array = this;
var booleans = await Promise.all(array.map(f));
return array.filter((x,i)=>booleans[i])
}
Late to the game but since no one else mentioned it, Bluebird supports Promise.map which is my go-to for filters requiring aysnc processing for the condition,
function filterAsync(arr) {
return Promise.map(arr, num => {
if (num === 3) return num;
})
.filter(num => num !== undefined)
}
Two lines, completely typesafe
export const asyncFilter = async <T>(list: T[], predicate: (t: T) => Promise<boolean>) => {
const resolvedPredicates = await Promise.all(list.map(predicate));
return list.filter((item, idx) => resolvedPredicates[idx]);
};
In case someone is interested in modern typescript solution (with fail symbol used for filtering):
const failSymbol = Symbol();
export async function filterAsync<T>(
itemsToFilter: T[],
filterFunction: (item: T) => Promise<boolean>,
): Promise<T[]> {
const itemsOrFailFlags = await Promise.all(
itemsToFilter.map(async (item) => {
const hasPassed = await filterFunction(item);
return hasPassed ? item : failSymbol;
}),
);
return itemsOrFailFlags.filter(
(itemOrFailFlag) => itemOrFailFlag !== failSymbol,
) as T[];
}
There is a one liner to to do that.
const filterPromise = (values, fn) =>
Promise.all(values.map(fn)).then(booleans => values.filter((_, i) => booleans[i]));
Pass the array into values and the function into fn.
More description on how this one liner works is available here.
For production purposes you probably want to use a lib like lodasync:
import { filterAsync } from 'lodasync'
const result = await filterAsync(async(element) => {
await doSomething()
return element > 3
}, array)
Under the hood, it maps your array by invoking the callback on each element and filters the array using the result. But you should not reinvent the wheel.
You can do something like this...
theArrayYouWantToFilter = await new Promise(async (resolve) => {
const tempArray = [];
theArrayYouWantToFilter.filter(async (element, index) => {
const someAsyncValue = await someAsyncFunction();
if (someAsyncValue) {
tempArray.push(someAsyncValue);
}
if (index === theArrayYouWantToFilter.length - 1) {
resolve(tempArray);
}
});
});
Wrapped within an async function...
async function filter(theArrayYouWantToFilter) {
theArrayYouWantToFilter = await new Promise(async (resolve) => {
const tempArray = [];
theArrayYouWantToFilter.filter(async (element, index) => {
const someAsyncValue = await someAsyncFunction();
if (someAsyncValue) {
tempArray.push(someAsyncValue);
}
if (index === theArrayYouWantToFilter.length - 1) {
resolve(tempArray);
}
});
});
return theArrayYouWantToFilter;
}
A valid way to do this (but it seems too messy):
let arr = [1,2,3];
function filter(num) {
return new Promise((res, rej) => {
setTimeout(() => {
if( num === 3 ) {
res(num);
} else {
rej();
}
}, 1);
});
}
async function check(num) {
try {
await filter(num);
return true;
} catch(err) {
return false;
}
}
(async function() {
for( let num of arr ) {
let res = await check(num);
if(!res) {
let index = arr.indexOf(num);
arr.splice(index, 1);
}
}
})();
Again, seems way too messy.
A variant of #DanRoss's:
async function filterNums(arr) {
return await arr.reduce(async (res, val) => {
res = await res
if (await filter(val)) {
res.push(val)
}
return res
}, Promise.resolve([]))
}
Note that if (as in current case) you don't have to worry about filter() having
side effects that need to be serialized, you can also do:
async function filterNums(arr) {
return await arr.reduce(async (res, val) => {
if (await filter(val)) {
(await res).push(val)
}
return res
}, Promise.resolve([]))
}
Late to the party, and I know that my answer is similar to other already posted answers, but the function I'm going to share is ready for be dropped into any code and be used.
As usual, when you have to do complex operations on arrays, reduce is king:
const filterAsync = (asyncPred) => arr =>
arr.reduce(async (acc,item) => {
const pass = await asyncPred(item);
if(pass) (await acc).push(item);
return acc;
},[]);
It uses modern syntax so make sure your target supports it. To be 100% correct you should use Promise.resolve([]) as the initial value, but JS just doesn't care and this way it is way shorter.
Then you can use it like this:
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
const isOdd = x => wait(1).then(()=>x%2);
(filterAsync(isOdd)([1,2,3,4,4])).then(console.log) // => [1,3]
Here's a shorter version of #pie6k's Typescript version:
async function filter<T>(arr: T[], callback: (val: T) => Promise<Boolean>) {
const fail = Symbol()
const result = (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i => i !== fail)
return result as T[] // the "fail" entries are all filtered out so this is OK
}
An efficient way of approaching this is by processing arrays as iterables, so you can apply any number of required operations in a single iteration.
The example below uses library iter-ops for that:
import {pipe, filter, toAsync} from 'iter-ops';
const arr = [1, 2, 3]; // synchronous iterable
const i = pipe(
toAsync(arr), // make our iterable asynchronous
filter(async (value, index) => {
// returns Promise<boolean>
})
);
(async function() {
for await (const a of i) {
console.log(a); // print values
}
})();
All operators within the library support asynchronous predicates when inside an asynchronous pipeline (why we use toAsync), and you can add other operators, in the same way.
Use of Promise.all for this is quite inefficient, because you block the entire array from any further processing that can be done concurrently, which the above approach allows.

Categories