Reputation: 449
I've working on a Chrome extension which is going to collect information from the Chrome.System apis and make use of all that data at once. The problem of course is that these calls are asynchrounous. I've not got a ton of experience with JS, so I want to make sure I'm doing this the easiest way possible.
The only way I can think of is making nested functions in the callbacks.
Something Like:
chrome.identity.getProfileUserInfo(function(userinfo){
getLocalIPs(userinfo.email, function(email, ips){
//keep passing data and nesting here.... and then do something after all calls are made
}
}
This seems like it will get very hard to read the code very quickly. What's the recommened method to do something like this. With synchronous programming, I would want to accomplish something like this:
var email = getEmail();
var ip = getIP();
var processor = getProcessor();
dosomething(email, ip, processor);
Upvotes: 1
Views: 613
Reputation: 395
Update:
It's 2019 and Promises are well supported in browsers. So see Xan's answer
Original Answer:
The nested functions become a burden a few levels in. I would suggest running each asynchronous call in order, and setting a flag for each callback on completion.
I would then create a function runIfReady()
which checks if all required flags are set before launching doSomething()
. You can add runIfReady()
to the end of every asynchronous callback. Once all of the details are in, the doSomething()
will run immediately.
You do not have to worry about launching doSomething()
multiple times, because although the callbacks are asynchronous, only one will run at a time.
Upvotes: 1
Reputation: 77502
Why reinvent the wheel when JavaScript already natively has tools to deal with it?
Specifically, Promises. There's a very good article at HTML5Rock introducing the concept.
You make functions that return promises:
function getEmailPromise() {
return new Promise(function(resolve, reject) {
chrome.identity.getProfileUserInfo(function(userinfo) {
resolve(userinfo.email);
});
});
}
And then you can do exactly what you want:
var email = getEmailPromise();
var ip = getIPPromise();
var processor = getProcessorPromise();
Promise.all([email, ip, processor]).then(function(data) {
// data is [email, ip, processor]
});
Upvotes: 7