All you need to know about Callbacks, Promises, Generators

Post on 16-Apr-2017

344 views 0 download

Transcript of All you need to know about Callbacks, Promises, Generators

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@example.com', (err, email) => { if (err) { return console.log(err); } console.log('Successfully validated:', email);});

Successfully validated: email@example.com

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?