Javascript ES6 generators

22
ES6 GENERATORS RAMESH NAIR HIDDENTAO.COM AUGUST 13, 2014 TAIPEI JAVASCRIPT ENTHUSIASTS

description

Javascript ES6 Generator explained.

Transcript of Javascript ES6 generators

Page 1: Javascript ES6 generators

E S 6 G E N E R AT O R S

R A M E S H N A I R H I D D E N TA O . C O M !A U G U S T 1 3 , 2 0 1 4 TA I P E I J A VA S C R I P T E N T H U S I A S T S

Page 2: Javascript ES6 generators

GENERATOR

A Generator generates values

Until no more values are available

Page 3: Javascript ES6 generators

S I M P L E G E N E R AT O R

var helloWorld = function*() {! yield 'hello';! yield 'world';!}

This function returns

a generatorThis generator “yields”

two strings

Page 4: Javascript ES6 generators

S T E P - B Y- S T E P

{ value: 'hello', done: false }

var gen = helloWorld();

var helloWorld = function*() {! yield 'hello';! yield 'world';!}

var value1 = gen.next();

console.log( value1 );

var value2 = gen.next();

console.log( value2 );{ value: 'world', done: false }

var value3 = gen.next();

console.log( value3 );{value: undefined, done: true}

Page 5: Javascript ES6 generators

F I B O N A C C I

var fib = function*() { let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; }}

1, 2, 3, 5, 8, 13, 21, …

Page 6: Javascript ES6 generators

F O R - O F

var fib = function*() { let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; }}!for (let n of fib()) { print(n); // 1, 2, 3, 5, 8, 13,…}

Page 7: Javascript ES6 generators

But yielding values isn’t that useful on its own

What if we could feed values back in?

Page 8: Javascript ES6 generators

F E E D I N G

{ value: 'hello', done: false }

var gen = helloWorld();

var value1 = gen.next();

console.log( value1 );

var value2 = gen.next(‘my’);

console.log( value2 );

{ value: ‘my world', done: false }

var helloWorld = function*() {! var v = yield 'hello';! yield v + ' world';!}

A yield is

synchronous

Page 9: Javascript ES6 generators

So what would happen if we yielded a Promise?

Page 10: Javascript ES6 generators

Y I E L D P R O M I S E S

Looks like a synchronous

call!

var gen = showUser();

var promise = gen.next().value;

promise.then(function(user) {!! gen.next(user);!});

var showUser = function*() {! var user = yield $.get(“/getUser?id=1”);! alert( user.name );!}

Page 11: Javascript ES6 generators

Y I E L D M A N Y P R O M I S E S

var gen = showStats();

var promise1 = gen.next().value;

promise1.then(function(user) {!!!!!});

var showStats = function*() {! var user = yield $.get(“/getUser?name=bob”);! var stats = yield $.get(“/stats/” + user.id);!! …!}

Repeats

! ! promise2.then(function(stats) {!! ! ! gen.next(stats);!! ! });!

var promise2 = gen.next(user).value;

Page 12: Javascript ES6 generators

C O - R O U T I N E S

var co = function(gen) {!! (var _next = function(res) {!! ! var yielded = gen.next(res);!! ! if (!yielded.done) {!! ! ! yielded.value.then(_next);!! ! }!! })();!}!!co(showStats());

var showStats = function*() {! var user = yield $.get(“/getUser?name=bob”);! var stats = yield $.get(“/stats/” + user.id);!! …!}

Page 13: Javascript ES6 generators

E R R O R S

var gen = showUser();

var promise = gen.next().value;

promise.then(function(user) {!! gen.next(user);!})

var showUser = function*() {!!!!!!}

! .catch(function(err) {! !! gen.throw(err);!! });

yield $.get(“/getUser?id=1”);try {!! ! !} catch (err) {! // do something!}!

Can yield inside here

Page 14: Javascript ES6 generators

G E N E R AT E D E R R O R S

var gen = showUser();

try {!! var promise = gen.next().value;!} catch (err) {! console.error(err);!}!

var showUser = function*() {! throw new Error(‘fail’);!}

Page 15: Javascript ES6 generators

B E T T E R C O - R O U T I N E

var co = function(gen) { (var _next = function(err, res) { try { var yld = null;! if (err) { yld = gen.throw(err); } else { yld = gen.next(res); }! if (!yld.done) { yld.value.then(function(result){ _next(null, result); }).catch(_next); } } catch (err) { console.error(err); } })();};

Page 16: Javascript ES6 generators

C O - R O U T I N E M O D U L E S

• Bluebird

• Promise.coroutine()

• Returns a Promise

• Lets you yield promises. Must configure it to support other item types.

• co

• co()!

• Accepts a callback

• Lets you yield promises, thunks, generators, generator functions

Faster for Promises

More flexible yielding

Page 17: Javascript ES6 generators

P R O M I S E S - > G E N E R AT O R S

var readFile = // returns a Promise!var main = function() { return readFile('file1') .then(function(contents) { console.log(contents); return readFile('file2'); }) .then(function(contents) { console.log(contents); })}!main().catch(…);

var readFile = // returns a Promise!var main = function*() { console.log(yield readFile('file1')); console.log(yield readFile('file2')); }!co(main)(…);

Page 18: Javascript ES6 generators

PA R A L L E L P R O C E S S I N G

var readFile = // returns a Promise!var main = function*() { var files = [ yield readFile('file1'), yield readFile('file2') ]; ... // do stuff with files}!co(main)();

var readFile = // returns a Promise!var main = function*() { var files = yield [ readFile('file1'), readFile('file2') ]; ... // do stuff with files}!co(main)();

sequential parallel

Page 19: Javascript ES6 generators

E X P R E S S - > K O A

var express = require('express');var app = express();!app.use(function(req, res, next){ res.send('Hello World');});!app.listen(3000);

var koa = require('koa');var app = koa();!app.use(function*(next){ this.body = 'Hello World';});!app.listen(3000);

Easier to control order of middleware execution…

Page 20: Javascript ES6 generators

K O A M I D D L E W A R E

• Waigo (waigojs.com) - web framework built around Koa

var koa = require('koa');var app = koa();!app.use(function*(next) { try { yield next; } catch (err) { // handle err }});!app.use(function*(next){ throw new Error('test');});

Execute rest of chain

Page 21: Javascript ES6 generators

A L S O C H E C K O U T…

• Iterators

• Simpler than generators

• Only return values, no feeding back in

• await!

• ES7 onwards

Page 22: Javascript ES6 generators

A N Y Q U E S T I O N S ?