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

Javascript ES6 generators

Jan 15, 2015

Download

Technology

Ramesh Nair

Javascript ES6 Generator explained.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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 ?