Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coordinating Asynchronous Requests in Javascript

I want to get two resources using two asynch calls. I want to proceed only when both resources have been retrieved.

How can I do this elegantly in JS?

This would work:

getStuff1(function (result1) {
    getStuff2 (function (result2) {
        // do stuff with result1 and result2
        ....
    }
}

but stuff2 only starts after stuff1 completes. I'd prefer to start stuff2 while waiting on stuff1.

like image 435
Gilbert Avatar asked Jul 09 '10 22:07

Gilbert


People also ask

How does JavaScript handle asynchronous code?

JavaScript provides three methods of handling asynchronous code: callbacks, which allow you to provide functions to call once the asynchronous method has finished running; promises, which allow you to chain methods together; and async/await keywords, which are just some syntactic sugar over promises.

What are asynchronous operations in JavaScript?

Asynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished. Once that task has finished, your program is presented with the result.

Is JavaScript synchronous or asynchronous?

JavaScript is Synchronous Spoiler: at its base, JavaScript is a synchronous, blocking, single-threaded language. That just means that only one operation can be in progress at a time.

What are asynchronous requests?

Asynchronous request — Where the client continues execution after initiating the request and processes the result whenever the AppServer makes it available.

How to write asynchronous code in JavaScript?

Methods for writing asynchronous JavaScript There are two ways of writing asynchronous code in JavaScript, promises and async/await.

Is it possible to send HTTP requests as asynchronous?

@jfriend00 The http requests can be asynchronous, I'm fine with that. I just need the program to be synchronous. for example to get notify when one http got a response and then send the next one, I guess I can use some form of callback, but I'm not sure how to implement that, since I don't have a list of all the requests before runtime.

How do you use async in a POST request?

For a POST request, the new information is stored in the body of the request. The async … await syntax is used with the Fetch API to handle promises. In the example code, the async keyword is used to make the getSuggestions () function an async function. This means that the function will return a promise.

What is an async function in JavaScript?

An async function returns a promise, if the functions returns a value, the promise is resolved with the value, but if the async function throws an error, the promise is rejected with that value. Let’s create a simple async function below: Here, we are declaring a function called favoriteDrink() which returns Monster energy drink.


Video Answer


2 Answers

If you know that functions are in fact first-class objects in Javascript, you can come up with a fairly elegant solution.

Without any extra objects, or global variables.

function callback1() {
  callback1.done = true;
  commonCallback();
}

function callback2() {
  callback2.done = true;
  commonCallback();
}

function commonCallback() {
  if (callback1.done && callback2.done) {
    // do stuff, since you know both calls have come back.
  }
}

Why is this so elegant? Because you've encapsulated the data, your scope is free from useless variables and the code is more readable than ever. How cool is that? :)


UPDATE

And if you want a bit more general solution you may try the following:

function callback() {
  callback.number -= 1;
  if (callback.number === 0) {
    // do stuff since all calls finished
    callback.last();
  }
}
callback.newQueue = function(num, last) {
  callback.number = num;
  callback.last   = last;
}

// EXAMPLE USAGE

// our last function to be invoked
function afterEverythingDone(){ alert("done"); }

// create a new callback queue
callback.newQueue(3, afterEverythingDone);

// as time passes you call the callback
// function after every request
callback();
callback();
callback();

// after all call is finished
// afterEverythingDone() executes

Awesomeness again :)

like image 165
25 revs, 4 users 83% Avatar answered Oct 13 '22 23:10

25 revs, 4 users 83%


One way is to use the same callback for both requests and proceed when both are complete:

var requestStatus = {
  fooComplete: false,
  barComplete: false
};

function callback(data) {
  if (isFoo(data)) {
    requestStatus.fooComplete = true;
  } else if (isBar(data)) {
    requestStatus.barComplete = true;
  }

  if (requestStatus.fooComplete && requestStatus.barComplete) {
    proceed();
  }
}

getAsync("foo", callback);
getAsync("bar", callback);

You'll probably want to flesh this out into a class.

Edit: added the async calls for clarity

like image 40
lawnsea Avatar answered Oct 13 '22 23:10

lawnsea