SALT Slides - Callbacks and Promises
SALT Slides - Callbacks and Promises
JAVASCRIPT
SYNCHRONOUS EXECUTION
ASYNCHRONOUS EXECUTION
Now we are getting more things done...
... in roughly the same amount of time!
BLOCKING CODE
const heavyCalcSync = (iterations) => {
while (iterations > 0) {
iterations--
}
return 'Heavy calc done!';
}
el.innerHTML += 'Before<br>';
el.innerHTML += heavyCalcSync(9999999999);
el.innerHTML += '<br>After';
}
Run Clear
el.innerHTML += 'Before\n';
somethingAsync(2000, (str) => {
el.innerHTML += str;
});
el.innerHTML += 'After\n';
}
Run Clear
So why shouldn't I just write all my functions to be asynchronous using
callbacks??
Complexity in writing and testing.
🔥CALLBACK HELL 🔥
Nested callbacks will quickly lead to unmaintainable code.
TYPICAL CODE USING CALLBACKS
const listOpenAccounts = (credentials, user, callback) => {
authorize(credentials, (err) => {
if (err) {
console.error('Authorization failure', err);
return callback(err);
}
result
.then(r => console.log(r)) // the promise is rejected
.catch(err => console.log('error: ', err)); // error: ...
PROMISES ARE CHAINABLE
Promise.prototype.then returns a new promise!
const txt = new Promise(resolve => resolve('foo'));
txt
.then(t => t + ' bar')
.then(t => t + ' baz')
.then(t => console.log(t)) // 'foo bar baz'
.catch(err => console.log(err));
AVOIDING CALLBACK HELL
Callbacks
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
Promises
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log('Got the final result: ' + finalResult))
.catch(failureCallback);
PROMISE.ALL
const weatherPromise = new Promise(
resolve =>resolve({ monday: '19 deg', tuesday: '21 deg' })
);
const trafficPromise = new Promise(
resolve => resolve({ lindhagenvägen: 'mild traffic, no queues' })
);
const openingHoursPromise = new Promise(
resolve => resolve({ eatery: 'open: 10.00 - 20.00' })
);
total
.then(r => console.log(r))
.catch(err => console.log('error:', err.message)); // haw haw
// tests.js
const assert = require('assert');
const api = require('./api.js');
// tests.js
const assert = require('assert');
const api = require('./api.js');
describe('promises', () => {
it('should validate that promise is resolved', (done) => {
api.imOk()
.then((val) => {
assert.strictEqual('foo', val);
done();
}).catch((err) => { // <-- add catch to avoid timeout for rejects
assert.fail('ImOk should not end up in catch');
});
});
This looks an awful lot like the callback hell we just left!
PRO TIPS ON CALLBACKS
https://appliedtechnology.github.io/protips/passingFunctions
https://appliedtechnology.github.io/protips/callingBack
https://appliedtechnology.github.io/protips/writingDeepFunctions
https://appliedtechnology.github.io/protips/makingPromises