Execute several promises in parallel, but only retrieve result from one of them

Viewed 72

I currently have a program where I want to call several REST API:s in parallel, but I'm only interested in the result from one of them.

Currently I've solved it like this:

private async loadData () {
    const all = [this.loadFirstData(), this.loadSecondData(), this.loadThirdData()];
    const combine = Promise.all(all);
    await combine;

    // One of the promises just puts it's return value in this global variable, so that I can access it after it is done.
    if (this.valueFromThirdAPI) {
        // Do something with value
    }
}

So what I do is just put the put the result from the promise I want a result from in a global variable that I can access after all of the promises have returned. This works, but I'm sure there must be a much better way of doing this.

Promises.all returns a array of the resolved values, but how do I distinguish them from each other if I'm only interested in the value from one of them? The other two doesn't need to return anything.

Thanks in advance!

4 Answers

First, it makes sense to await Promise.all,

You can access the result using the returned array's index. Another option is using Array destructoring.

Below is an example..

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve('this one');
const promise4 = Promise.resolve(4);

async function test() {
  //note the double `,` to ignore the first 2 promises.
  const [,,three] = await Promise.all([promise1, promise2, promise3, promise4]);
  console.log(three);
}

test();

Promise.all returns an array with the same order of the given promises:

private async loadData () {
    const all = [this.loadFirstData(), this.loadSecondData(), this.loadThirdData()];
    const combine = Promise.all(all);
    const values = await combine;

    // One of the promises just puts it's return value in this global variable, so that I can access it after it is done.
    if (values[2]) {
        // Do something with value
    }
}

Wait on the third and then await on all. So if the third finishes before first and second, you get to process it earlier.

private async loadData () {
    const all = [this.loadFirstData(), this.loadSecondData(), this.loadThirdData()];
    const third = await all[2];
    if (third) {
        // Do something with value
    }

    await Promise.all(all);
}
Related