Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Javascript ES6 generators

3,815 views

Published on

Javascript ES6 Generator explained.

Published in: Technology
  • Be the first to comment

Javascript ES6 generators

  1. 1. 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
  2. 2. G E N E R AT O R A Generator generates values … Until no more values are available
  3. 3. 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
  4. 4. 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}
  5. 5. 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, …
  6. 6. 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,… }
  7. 7. But yielding values isn’t that useful on its own What if we could feed values back in?
  8. 8. 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
  9. 9. So what would happen if we yielded a Promise?
  10. 10. 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 );! }
  11. 11. 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;
  12. 12. 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);! ! …! }
  13. 13. 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
  14. 14. 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’);! }
  15. 15. 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); } })(); };
  16. 16. 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
  17. 17. 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)(…);
  18. 18. 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
  19. 19. 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…
  20. 20. K O A M I D D L E WA 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
  21. 21. 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
  22. 22. A N Y Q U E S T I O N S ?

×