0

I make a async call to get some data. Then, I need to make 3 async calls. After those 3 calls finish I want to do something else. I've tried this:

let outerApi;

getApi(url).then(function(api) {
  outerApi= api;
  return doSomething(api, "cars");
}).then((cars) => {
   //3 async calls
   call1(outerApi, cars);                 
   call2(outerApi, cars);             
   call3(outerApi, cars);
}).then(call1ReturnValue, call2ReturnValue, call3ReturnValue => {
   doSomething(call1ReturnValue, call2ReturnValue, call3ReturnValue);
});

The value pass to doSomething are all undefined. How can I wait for the 3 async calls to complete? I know how to do this as the first step of chain via Promise.all but not sure how this is accomplished in a then.

Update

Thanks all for the feedback. Here's what I tried:

Replacing then with Promise.all as suggested by @ControlAltDel:

let outerApi;

getApi(url).then(function(api) {
  outerApi= api;
  return doSomething(api, "cars");
}).Promise.all([
   //3 async calls
   call1(outerApi, cars),                 
   call2(outerApi, cars),             
   call3(outerApi, cars)])
).then(call1ReturnValue, call2ReturnValue, call3ReturnValue => {
   doSomething(call1ReturnValue, call2ReturnValue, call3ReturnValue);
});

The results in an error:

Uncaught TypeError: Cannot read properties of undefined (reading 'all')

As suggested by @DannyMoshe, return Promise in first then:

let outerApi;

getApi(url).then(function(api) {
  outerApi= api;
  return doSomething(api, "cars");
}).then((car) => {
   return Promise.all([
   //3 async calls
   call1(outerApi, cars),                 
   call2(outerApi, cars),             
   call3(outerApi, cars)]);
).then(call1ReturnValue, call2ReturnValue, call3ReturnValue => {
   doSomething(call1ReturnValue, call2ReturnValue, call3ReturnValue);
});

call2ReturnValue & call3ReturnValue are undefined when calling doSomething.

My solution

let outerApi;

getApi(url).then(function(api) {
  outerApi= api;
  return doSomething(api, "cars");
}).then((car) => {
   return Promise.all([
   //3 async calls
   call1(outerApi, cars),                 
   call2(outerApi, cars),             
   call3(outerApi, cars)]);
).then(([call1ReturnValue, call2ReturnValue, call3ReturnValue]) => {
   doSomething(call1ReturnValue, call2ReturnValue, call3ReturnValue);
});

From Promise.all documentation, the fulfulliment values are an array of fulfillment values. My previous attempt was not expecting an array.

James
  • 2,876
  • 18
  • 72
  • 116
  • See Promise.all(...) – ControlAltDel Aug 11 '23 at 16:33
  • "*not sure how this is accomplished in a `then`.*" - in exactly the same way. `Promise.all` returns a promise, and you can use that in promise chaining like any other (like you already did with `return doSomething(…)`, for example) – Bergi Aug 11 '23 at 16:36
  • @ControlAltDel - Thanks for the link. I'm aware of `Promise.all` but how could I use that in a `then`. I would prefer not to have a nested `then`. – James Aug 11 '23 at 16:37
  • 1
    Just declare the promises: `call1Promise = call1(outerApi, cars); call2Promise = call2(outerApi, cars); call3Promise = call3(outerApi, cars);` and return `Promise.all([call1Promise, call2Promise, call3Promise])` in the first then – DannyMoshe Aug 11 '23 at 16:39
  • 1
    @James [You don't have to nest the `.then()` calls](https://stackoverflow.com/a/22000931/1048572) (although [there is nothing wrong with nesting](https://stackoverflow.com/a/28250687/1048572) either) – Bergi Aug 11 '23 at 16:41
  • @ControlAltDel - Thanks for the help. I'm getting `Uncaught TypeError: Cannot read properties of undefined (reading 'all')` when replacing `then` with `Promise.all` – James Aug 11 '23 at 16:51
  • 1
    @James I'd suggest looking at the documentation for `Promise.all` rather than just assuming you can paste it in place of `.then` as you have. – Kevin B Aug 11 '23 at 17:57
  • @KevinB - Thanks for your comment. Thanks to all the feedback and looking at the documentation, I see that Promise.all fulfillment value is an array of fulfillment values, in the order of the promises passed. I'll update my OP with my solution using the much appreciated help of everyone here. – James Aug 11 '23 at 18:28
  • @ControlAltDel, Bergi, thanks to both of you. I'm new to this part of JS. So thanks for bearing with me. – James Aug 11 '23 at 18:28

0 Answers0