Upload
brainhub
View
344
Download
0
Embed Size (px)
Citation preview
CALLBACKS,
PROMISES,
GENERATORS
Adam GołąbFull Stack Developer at
In computer programming, a callback is a piece of executable codethat is passed as an argument to other code, which is expected to
call back (execute) the argument at some convenient time.
Callbacks
Good Practice
Run ►
function validate(email, cb) { if (email.match(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)+$/)) { return cb(null, email); } return cb(new Error('incorrect email address'));}
validate('[email protected]', (err, email) => { if (err) { return console.log(err); } console.log('Successfully validated:', email);});
Successfully validated: [email protected]
12345678910111213
For a function to be asynchronous it needs to perform an
asynchronous operation. It needs to incorporate the argument
callback in handling the results of this asynchronous operation.
Only this way the function becomes asynchronous.
Asynchronous
Async Callback
Run ►
function callAsync(fn) { setTimeout(fn, 0);}
callAsync(() => console.log('callback function'));console.log('after');
aftercallback function
123456
AJAX request
Run ►
const request = require('request');
request('http://localhost:3000/api', (err, res, body) => console.log(body));
Response from server
123
IO operation
Run ►
const fs = require('fs');
fs.readFile('./file.txt', 'utf-8', (err, data) => {
if(!err) {
console.log(data);
}
});
Hello from file
1
2
3
4
5
6
7
Pyramid from hell
Run ►
const request = require('request');
const fs = require('fs');
request('http://localhost:3000/api', (err, res, body) => {
if (!err) {
fs.readFile('./file.txt', 'utf-8', (err, data) => {
if (!err) {
[data, body].map((text, index) => {
console.log(index, text);
});
}
});
}
});
0 'Hello from file\n'
1 'Response from server'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PromisesThe Promise object is used for asynchronous computations. A
Promise represents a value which may be available now, or in thefuture, or never.
new Promise( function(resolve, reject) { ... } );
Promises
Run ►
const a = 4;const b = 2;const p = new Promise((resolve, reject) => { if (b === 0) { reject(new Error('Do not divide by zero')); } resolve(a / b);});
p.then(value => console.log(value)).catch(err => console.error(err));
2
12345678910
AJAX Fetch
Run ►
const fetch = require('node-fetch'); // there is no window.fetch on node.js
fetch('http://localhost:3000/api').then(res => res.text()).then(body => console.log(body));
Response from server
12345
Run ►
No more callback hellconst fetch = require('node-fetch');
const fs = require('fs');
function readFilePromised(file) {
const p = new Promise((resolve, reject) => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) {
reject(err);
}
resolve(data);
});
});
return p;
}
Promise.all([
readFilePromised('./file.txt'),
fetch('http://localhost:3000/api').then(r => r.text())
])
.then((responses) => responses.map((text, index) => {
console.log(index, text);
}));
0 'Hello from file\n'
1 'Response from server'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Generatorsis a special routine that can be used to control the iteration
behaviour of a loop. In fact, all generators are iterators
Pausable functions
Run ►
Natural numbers generatorfunction *naturalNumbers() { let x = 0; while (true) { x = x + 1; yield x; }}
const generator = naturalNumbers();console.log(generator.next());console.log(generator.next());console.log(generator.next());
{ value: 1, done: false }{ value: 2, done: false }{ value: 3, done: false }
123456789101112
Async generator
Run ►
const fetch = require('node-fetch');const co = require('co');
co(function *() { const uri = 'http://localhost:3000/api'; const response = yield fetch(uri); const body = yield response.text(); console.log(body);});
Response from server
123456789
Run ►
Co function implementationconst fetch = require('node-fetch');
function co(generator) { const iterator = generator(); const iteration = iterator.next(); function iterate(iteration) { if (iteration.done) { return iteration.value; } const promise = iteration.value; return promise.then(x => iterate(iterator.next(x))); } return iterate(iteration);}
co(function *() { const uri = 'http://localhost:3000/api'; const response = yield fetch(uri); const body = yield response.text(); console.log(body);});
Response from server
123456789101112131415161718192021
Questions?