Asynchronous calls are an inherent part of javascript, and using callbacks is often an elegant tool to handle these calls.
However, I am not quite sure how is the branching of code following an asynchronous operation decided. For example, what would happen with the following code?
function f(callback) {
value = some_async_call();
if (value) {
callback(value);
}
return(value);
}
What would happen here? From my short JS experience, return
would send back an undefined
value. But suppose that value
returns true from the asynchronous call, would the callback be called with the right value or with an undefined
value?
In other words, is there a rule regarding which operations are executed immediately after the async call, and which are deferred until the value is returned?
SFTW for branching asynchronous calls in javascript, but found nothing canonical or decisive.
update: added a practical difference between the 3 different approaches at the bottom
let's assume some_async_call();
is defined as an async function: async function some_async_call() { ... }
what this function returns is a Promise
, which means that value
is now a promise: value.then( function(result) { } )
when i translate this into code:
async function some_async_call() {
if (theMoonIsInTheRightPosition)
return Fetch('/api/data/') // this returns a promise as well.
return false;
}
i can now do 2 things:
function parentFunction(callback) {
var promise = some_async_call();
promise.then( callback );
return ...; // you can't "return" the value of an async call synchronously, since it is a promise.
}
or:
async function asyncParentFunction( callback ) {
var value = await some_async_call();
if (value)
callback( value );
return value;
}
however, this transforms the parent-function into an async function as well, which means the immediate return value of that function... is a promise as well.
You either use callbacks to flow through your asynchronous functions, or promises, or async/await
callbacks
function doStuff(callback) {
// do asynchronous stuff
var result = 100;
callback(result); // once you're done with stuff
}
doStuff( function(data) { console.log('Im done!', data); } );
promises
function doStuff() {
return new Promise(function(resolve, reject) {
// do asynchronous stuff
var result = 100;
resolve(result);
});
}
doStuff.then(function(data) { console.log('Im done!', data); });
async/await
function doStuff() {
return new Promise(function(resolve, reject) {
// do asynchronous stuff
var result = 100;
resolve(result);
});
}
(async function() { // async/await only works in async functions.
var data = await doStuff();
console.log('Im done!', data);
})();
as you can see: promises and async/await use the same mechanism and are really worth reading into.
callbacks
function fetchUserWithPosts(userId, callback) {
fetchUser(userId, function(user) {
fetchPostsByUserId(userId, function(posts) {
callback({
user: user,
posts: posts
});
});
});
}
promises
function fetchUserWithPosts(userId) {
return Promise.all([
fetchUser(userId),
fetchPostsByUserId(userId)
]).then(function(result) {
return {
user: result[0],
posts: result[1]
};
});
}
async/await
async function fetchUserWithPosts(userId) {
return {
user: await fetchUser(userId),
posts: await fetchPostsByUserId(userId);
};
}
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