HardCoreQual
HardCoreQual

Reputation: 391

How properly synchronous resolve list of promises in typescript / javascript

I have list of promises what obtain data from database, modify it and save, some promises can work with same data, to exclude possible conflicts, I decide execute promise synchronous, I write next function, but I suspect that it can be done more simply and the rule.

Typescript

async function syncPromises<T>(arr: (() => Promise<T>)[]) {
  const result : T[] = [];

  for(const fn of arr) {
    result.push(await fn());
  }

  return result;
}

JavaScript

async function syncPromises(arr) {
  const result = [];

  for(const fn of arr) {
    result.push(await fn());
  }

  return result;
}

Currently I use similar code for call function

const ids = [ 3, 5 ];
syncPromises(ids.map(id => () => someLogicWhatNeedExecSync(id)));

I think this can be more simple

Upvotes: 0

Views: 1792

Answers (3)

Bergi
Bergi

Reputation: 664620

Instead of taking an array of functions, take an array of values and a single function to apply to them - basically map:

async function sequentialMap<V, R>(arr: V[], fn: (v: V) => Promise<R>): Promise<R[]> {
  const result : R[] = [];
  for (const value of arr) {
    result.push(await fn(value));
  }
  return result;
}

You can use it as

const ids = [ 3, 5 ];
sequentialMap(ids, someLogicWhatNeedExecSync);

Upvotes: 2

Sunny
Sunny

Reputation: 564

Absolutely agree with the approach mentioned by @Bergi. Another way can be to use Promise.all()

function asyncTimeoutFunction(id){
    return new Promise(resolve=>{
        setTimeout(()=>resolve(id),1000);
    })
}

const ids = [ 3, 5, 2 ];
const functions = ids.map((id)=>{
    return asyncTimeoutFunction(id);
});

Promise.all(functions).then(console.log);

Just replace your Asynchronous function with asyncTimeoutFunction.

Upvotes: 0

Felix Dolderer
Felix Dolderer

Reputation: 471

JavaScript and TypeScript have some subtleties when it comes to looping over functions you want to await.

This pages explains the options and differences very well: https://advancedweb.hu/how-to-use-async-functions-with-array-foreach-in-javascript/

If you want all promises to be resolved before returning, then you can't use a for-loop but should rather use arr.map() or arr.reduce()

In your case where you want to return an array, the easiest is probably to use a arr.map() as it returns an array.

Upvotes: 0

Related Questions