How to make a JavsScript callback wait for another callback?

Viewed 84

I'm required to make two API calls simultaneously. And one of the callback has to be executed before the other. But making the calls sequential is slow and bad for user experience:

axios.get("/get_some_data").then(function(resp) {
    do_some_operation();

    axios.get("/get_other_data").then(function(resp) {
            do_other_operation(); // Needs /get_some_data and /get_other_data both be done
        });
    });
});

Making parallel calls and wait for another can be done easily in C++ using std::conditional_variable with the following pseudo (C++17 ish) code

std::conditional_variable cv;
std::mutex mtx;

get_request("/get_some_data",[&](auto&& resp){
    do_some_operation();
    
    // Notify that the operation is complete. The other callback can proceed
    cv.notify_all();
});

get_request("/get_other_data",[&](auto&& resp){
    // Wait until someone notify the previous task is done
    std::lock_guard lk(mtx);
    cv.wait(lk);

    do_other_operation();
});

I've searched on various websites. But I don't think JavaScript comes with anything like std::conditional_variable or even a std::mutex. How could I make parallel requests but make a callback wait for another?

2 Answers

Sounds like you want something like this

const some = axios.get("/get_some_data").then(res => {
  do_some_operation()
  return res
})
const other = axios.get("/get_other_data")

Promise.all([some, other]).then(([ someRes, otherRes ]) => {
  do_other_operation()
})

This will call both URLs in parallel.

When the first resolves, it will call do_some_operation(). This (presumably) synchronous operation becomes part of the some promise resolution. The other promise resolves once the HTTP request completes.

Once both some and other promises are resolved, call do_other_operation()

Use promise all

Promise.all([
  get_request("/get_some_data"),
  get_request("/get_other_data")
]).then( function(responses) {
  console.log(responses);
  // do what you want
  do_some_operation();
  do_other_operation();
}).catch(function(error) { 
  console.error(error.message);
});

OR

Promise.all([
  get_request("/get_some_data").then(function (resp) {
    do_some_operation();
    return resp;
  },
  get_request("/get_other_data")
]).then( function(responses) {
  console.log(responses);
  // do what you want
  do_other_operation();
}).catch(function(error) { 
  console.error(error.message);
});
Related