Callbacks, Promises, and Generators

We are trying to get a seat at the cool kid's table. Important to becoming a good programmer is the ability to READ code; to accept, understand, and follow the reasoning the syntax takes us; one more time: we follow the code like we might follow a great story by any of a number great English authors. Likewise we learn to read the NodeJS solutions in JavaScript. Hence we become ONE with the code and relax.
Post Reply
User avatar
Posts: 148
Joined: Mon Apr 16, 2018 1:03 pm

Callbacks, Promises, and Generators

Post by james » Tue Apr 23, 2019 3:33 pm

Callbacks, Promises, and Generators


An obvious issue with callbacks is the increased indentation. This has been affectionately called the callback pyramid of doom.

The worst issue with using callbacks for async tasks is the complexity in error handling.

Now let’s look at a better way to tackle asynchronous JavaScript using promises.


Promise advantage: Instead of using a callback (which is an input) to provide the output, we return the promise, which can be used to subscribe for the output at your convenience.

Promise advantage: Since a promise’s transition into fulfilled or rejected is immutable, all individual onFulfilled / onRejected handlers will only be called once. Promises don’t have the called again problem of callbacks.

Promise advantage: Promises do not suffer from the maybe sync problem of callbacks. If you want to return an immediate promise, just return a resolved promise using Q.when and any then that the user registers is bound to be called asynchronously.

The chain-ability of promises is their most important feature. Once you have a promise, you use the then function to create a chain of fulfilled or rejected promises.

Promise advantage: Uncaught exceptions inside onFulfilled/onRejected handlers do not blow the application. Instead, they result in the promise in the chain to be rejected, which you can handle gracefully with a final onRejected handler

Promise advantage: Promises save you from an unneeded pyramid of doom.

Promise advantage: You are more prepared to handle the future language changes coming to JavaScript if you use promises


As a thought experiment, imagine the following: a way to tell the JavaScript runtime to pause the executing of code on the await keyword used on a promise and resume *only* once (and if) the promise returned from the function is settled.

Promises and Generators

var Q = require('q');
// an async function to load an item
var loadItem = Q.nbind(function (id, cb) {
setTimeout(function () {
cb(null, { id: id });
}, 500); // simulate delay
// An async function to load items
var loadItems = Q.async(function* (ids){
var items = [];
for (var i = 0; i < ids.length; i++) {
items.push(yield loadItem(ids));
return items;
Q.spawn(function* (){
console.log(yield loadItems([1,2,3]));

The Future

There is already an ECMAScript 7 recommendation to make async / await first-class usable keywords of the language, which provide very light sugar to do a transformation similar to what we have demonstrated.


Post Reply