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.
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.
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.
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.
Asynchronous request — Where the client continues execution after initiating the request and processes the result whenever the AppServer makes it available.
Methods for writing asynchronous JavaScript There are two ways of writing asynchronous code in JavaScript, promises and async/await.
@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.
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.
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.
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 :)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With