Promise Chaining
Objectives
-
Describe the disadvantages of using nested callbacks
-
Return a promise from a .then callback function
-
Use a promise to make asynchronous code seem sequential
Nested Async Callbacks
var counter = 0;
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
}, 3000);
}, 2000);
}, 1000);
Console:
Counter: 1
Counter: 2
Counter: 3
Disadvantages of Nested Callbacks
-
The code is hard to read
-
Logic is difficult to reason about
-
The code is not modular
Returning a Promise:
Promise Chaining
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
randomInt = Math.floor(Math.random() * 10);
resolve(randomInt);
}, 500);
});
promise.then(function(data) {
console.log("Random int passed to resolve:",
data);
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(Math.floor(Math.random() * 10));
}, 3000);
});
}).then(function(data) {
console.log("Second random int passed to resolve:",
data);
});
Promise Chaining:
Returning Data
var promise = new Promise(function(resolve, reject) {
resolve(5);
});
promise.then(function(data) {
return data * 2;
}).then(function(data) {
return data + 20;
}).then(function(data) {
console.log(data);
});
Console:
30
Nested Callbacks:
To Be Refactored
var counter = 0;
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
}, 3000);
}, 2000);
}, 1000);
Console:
Counter: 1
Counter: 2
Counter: 3
Step 1:
Create a Function Declaration
var counter = 0;
function incCounter() {
counter++;
console.log("Counter:", counter);
}
Step 2:
Create a runLater Function
var counter = 0;
function incCounter() {
counter++;
console.log("Counter:", counter);
}
function runLater(callback, timeInMs) {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
var res = callback();
resolve(res);
}, timeInMs);
});
return p;
}
Step 3: Chain Promises
var counter = 0;
function incCounter() {
counter++;
console.log("Counter:", counter);
}
function runLater(callback, timeInMs) {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
var res = callback();
resolve(res);
}, timeInMs);
});
return p;
}
runLater(incCounter, 1000).then(function() {
return runLater(incCounter, 2000);
}).then(function() {
return runLater(incCounter, 3000);
}).then(function() {
// final .then not necessary
});
Promise Refactor: Side By Side
var counter = 0;
function incCounter() {
counter++;
console.log("Counter:", counter);
}
function runLater(callback, timeInMs) {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
var res = callback();
resolve(res);
}, timeInMs);
});
return p;
}
runLater(incCounter, 1000).then(function() {
return runLater(incCounter, 2000);
}).then(function() {
return runLater(incCounter, 3000);
});
var counter = 0;
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
}, 3000);
}, 2000);
}, 1000);
It is useful to understand how promises work (resolve, reject), but in practice you will often use promises that are returned to you
Promises In Practice
Promise Chaining
By Elie Schoppik
Promise Chaining
- 2,872