This is an odd problem. I have a client object that I am building up using Crockford-esque public/private members:
var client = function() {
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
remote_data = jsonRequest1();
other_data = jsonRequest2();
return that;
};
The problem I'm having is that I need to load some remote JSON resources prior to returning the new 'that' object (which signals a ready client). Data is returned asynchronously (obviously), and I am setting boolean variables to indicate when each remote resource has returned.
I've thought about doing something like the following:
return whenInitialized(function() { return that; });
The whenInitialized function returns whether or not both of the boolean flags are true. I'd use this with a combination of setInterval, but I am sure this won't work.
Would appreciate your suggestions.
Promises handled with async/await To solve this with modern features, place the keyword async before the functions. Doing this enables the use of the keyword await within them. When used before some code that returns a promise, await prevents further function execution until the promise is returned.
– Async Function-Based Promises: Use the “Await” Function For async function-based promises, you may add the “await” function to stop the function in javascript, until the promise is fulfilled, and then return the result value.
You can do it using the return keyword. Whenever JavaScript sees the return keyword, it immediately exits the function and any variable (or value) you pass after return will be returned back as a result.
The delay is set in milliseconds and 1,000 milliseconds equals 1 second. If the delay is omitted from the setTimeout() method, then the delay is set to 0 and the function will execute. You can also have optional arguments that are passed into the function.
In order to run code after an asynchronous operation has succeeded, you need a continuation. It can be just a callback that your code calls when the operations are complete.
Something like this:
var client = function(done) { // done is the callback
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
var done1 = false, done2 = false;
var complete1 = function() { done1 = true; if (done2) done(); };
var complete2 = function() { done2 = true; if (done1) done(); };
remote_data = jsonRequest1(complete1);
other_data = jsonRequest2(complete2);
return that;
};
But these controlling flags are really annoying and don't really scale. A better, declarative way of doing this is using something like jQuery deferreds:
$.when(jsonRequest1(), jsonRequest2()).then(done);
You can do a loop (optionally with a timeout) to wait for the async to finish. Warning, this will (as requested) block all other functionality and may cause the browser to freeze if it takes much too long. However, you really should figure out an asynchronous way to do what you need instead of blocking like this.
var syncRequest = function(options) {
var is_finished = false;
var result;
var finished_callback = function(response) {
is_finished = true;
result = response.result;
}
ajax_request(options, finished_callback);
// timeout in 30 seconds
var timeout = (new Date()).getTime() + 30000;
while ( !is_finished ) {
if ( (new Date()).getTime() >= timeout ) {
alert('Request timed out');
}
// do nothing, just block and wait for the request to finish
}
return result;
}
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