Skip to content

Instantly share code, notes, and snippets.

@dyladan
Last active July 1, 2019 16:47
Show Gist options
  • Save dyladan/467b096d1c46f4599ec5ddda5085e161 to your computer and use it in GitHub Desktop.
Save dyladan/467b096d1c46f4599ec5ddda5085e161 to your computer and use it in GitHub Desktop.
This is an example of all the ways asynchronous operations may be carried out in javascript
/*
* First, we will declare some asynchronous functions to consume.
* These actually do not make asynchronous calls, but they illustrate
* the idea.
*/
// Callback style asynchronous function
function callbackAsyncFunction(val1, val2, callback) {
//processing
if (!val1) {
callback(new Error("val1 required"));
} else if (!val2) {
callback(new Error("val2 required"));
} else {
callback(null, val1 + val2)
}
}
// Promise implementation of the above callback
function promiseAsyncFunction(val1, val2) {
return new Promise(function(resolve, reject) {
if (!val1) {
reject(new Error("val1 required"));
} else if (!val2) {
reject(new Error("val2 required"));
} else {
resolve(null, val1 + val2)
}
})
}
// This is how it would be written in an async function. Notice it is actually
// exactly the same as a synchronous version of the function, but the async
// keyword means it implicitly retuns a promise
async function asyncFunction(val1, val2) {
if (!val1) {
throw new Error("val1 required");
}
if (!val2) {
throw new Error("val2 required");
}
return val1 + val2;
}
// Or we can cheat and "promisify" the callback so we don't have
// to reimplement the logic
function promisifiedAsyncFunction(val1, val2) {
return new Promise(function(resolve, reject) {
callbackAsyncFunction(val1, val2, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
/*
* Next, we will implement some functions to consume our asynchronous functions.
*/
// This function consumes the callbacks
// Notice that at some points err and data are overwritten
// This is referred to by javascript developers as "callback hell"
function callbackConsumer(val1, val2, cb) {
callbackAsyncFunction(val1, val2, function(err, data) {
if (err) {
// handle error
} else {
callbackAsyncFunction(data, val2, function(err, data) { // IMPORTANT: err and data shadow the above scope
if (err) {
// handle error
cb(err)
} else {
// process data
cb(null, data)
}
});
}
});
}
// This is the same logic implemented in promises
// Notice that the "data" variable is not overwritten but actually is in a new scope
// Variables declared in the first .then handler are not available in subsequent handlers
function promiseConsumer(val1, val2) {
return promiseAsyncFunction(val1, val2)
.then(function(data) {
return promiseAsyncFunction(data, val2);
})
.then(function(data) { // this is a new data object, it is not overwriting the old one
// process data
if (somethingBad) {
// promise functions throw just like their synchronous counterparts,
// but errors are handled in the .catch handler rather than a try/catch block
throw new Error("something bad happened")
}
return processedData;
})
.catch(function(err) { // catch removes conditional error handling and decreases human error
// handle error
})
}
// This is the new Async/Await style consumer
// Any function that returns a promise can be awaited, and all async functions return promises no matter what
async function asyncPromiseConsumer(val1, val2) {
try { // async functions handle errors in normal try/catch blocks
// call asynchronous functions just like synchronous functions
// this can only be done in functions explicitly marked async
let data = await promiseAsyncFunction(val1, val2);
data = await promiseAsyncFunction(data, val2);
// process data
if (somethingBad) {
// async functions throw just like their synchronous counterparts
// errors will go to the catch block just like synchronous programming
throw new Error("something bad happened")
}
return processedData; // This implicitly returns as a promise
} catch (err) {
// handle error
}
}
@gaycomputers
Copy link

Nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment