2

I have 2 function that return promises, P1 and P2. First I want to wait until P1() is fulfilled, then I want to execute P2 and when P2() is fulfilled I want to do something with the value P1() resolved to. It is easy to do using async/await like this:

const result = await P1()
await P2()
doSomething(result)

but I cant use async/await. Using promises I can do it like this:

P1().then((result) => P2().then(() => result)).then((result) => doSomething(result))

but is there any prettier way to do it (without nested thens)?

lukasbalaz7
  • 360
  • 2
  • 11
  • 1
    Nesting `then` is just a fine solution, but you can simplify to `P1().then(result => P2().then(() => doSomething(result)))` – Bergi Nov 22 '17 at 13:44

2 Answers2

4

You could use Promise.all like this, it waits until all promises have been resolved (or the first rejection).

Promise.all([p1, p2]).then(result => { 
  doSomething(result);
});

or the more terse:

Promise.all([p1, p2]).then(result => doSomething(result));
curv
  • 3,796
  • 4
  • 33
  • 48
  • or more terse: `Promise.all([p1, p2]).then(doSomething)` – dfsq Nov 22 '17 at 13:29
  • haha yer or that :-D – curv Nov 22 '17 at 13:31
  • Ahh I will need to update my question. `P1` and `P2` should be functions that return promises. I just wanted to make it simpler and I didn't realize it is so different :) The point is, if `P2` is a function, I want to execute it **after** `P1()` is fulfilled – lukasbalaz7 Nov 22 '17 at 13:33
  • In that case, what you had originally is the way to go, there is no other way I am aware of, so this maybe? Also depends on if you want to pass the result from P1? It's a little shorter... P1().then(() => P2().then(result => doSomething(result))); – curv Nov 22 '17 at 13:44
1

It seems that P1 and P2 are independent, as you are not using the value of P1 to start the call of P2. If that's the case you can use .all() method to run those 2 promises in parallel, and then do something with their results.

Promise.all([P1, P2]).then(([ P1Result, P2Result ]) => {
  doSomething(P1Result, P2Result);
});

However if P2 does depends on P1, the nested .then() would be the way to go. I've created a tiny module to ease the calls of promises in series, where it is even possible to mix sync and async methods on the same pipeline. Take a look and see if that can help you on getting rid of writing the nested .then() methods: https://github.com/DiegoZoracKy/pipe-functions

Diego ZoracKy
  • 2,227
  • 15
  • 14