ES6 Generators
Feel the *power
Avoid callback inception
Avoid callback inception
$el.on('click', function(evt) {
$.ajax('/vsearch/pj', function(data) {
dust.render('tl/shared/person', data, function
(err, out) {
$el.html(out);
// Please, make it stop!
})
})
});
Example
> function *hoover() {
console.log('Preparing to yield "Boulder"');
yield 'Boulder';
console.log('All done yielding');
}
> let iter = hoover();
// Nothing happens...
> iter.next();
'Preparing to yield "Boulder"'
Object {value: "Boulder", done: false}
> iter.next();
'All done yielding'
Object {value: undefined, done: true}
Iterators
Behind every Generator is a great Iterator
next()
next()
All an object needs to be an iterator is a next* method, which
returns an object with a value property and a done property.
* Iterators generally also include a throw method for throwing errors.
for … of
function *hoover() {
console.log('Preparing to yield "Boulder"');
yield 'Boulder';
console.log('All done yielding');
}
for (let x of hoover()) {
console.log(`x is ${x}`);
}
// Output:
/*
Preparing to yield "Boulder"
x is Boulder
All done yielding
*/
Iterables
● Arrays
● Maps
● Sets
Iterables
let vals = ['a', 'b', 'c'];
for (let x of vals) {
console.log(`x is ${x}`);
}
// Output:
/*
'a'
'b'
'c'
*/
// Python lovers rejoice
Yield
Yield
Fibonacci Generator
function *fibGenerator() {
let prev1 = 1;
let prev2 = 0;
let current;
yield prev2;
yield prev1;
while (true) {
current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
yield current;
}
}
Using the Fibonacci Generator
var fib = fibGenerator();
console.log(fib.next());
0
console.log(fib.next());
1
console.log(fib.next());
1
console.log(fib.next());
2
console.log(fib.next());
3
console.log(fib.next());
5
Wait for it...
Prompt
We already know how to pause execution in the middle of
a function.
function getName() {
var name = prompt('What's your name?');
return name;
}
But now we can pause execution without freezing the entire
browser.
Wait for it...
Avoid callback inception
$el.on('click', function(evt) {
$.ajax('/vsearch/pj', function(data) {
dust.render('tl/shared/person', data, function
(err, out) {
$el.html(out);
// Please, make it stop!
})
})
});
remember?
yield is the new callback
function *showFeed() {
let data = yield request('/feed');
let dom = yield feedTemplate.render(data);
document.querySelector('#feed-container').appendChild(dom);
}
// To use
runMyGenerator(showFeed);
Behind the Scenes - request
function request(url) {
if (cachedResponses[url]) {
return cachedResponses[url];
} else {
return Promise(function(resolve, reject) {
makeAjaxRequest(url, resolve);
});
}
}
Behind the Scenes - runMyGenerator
function runMyGenerator(gen) {
let iter = gen();
let yielded;
(function iterate(val) {
yielded = iter.next(val);
if (!yielded.done) {
if ('then' in yielded.value) {
// Wait for the promise to resolve before the next iteration
yielded.value.then(iterate);
} else {
// Next
setTimeout(function() {
iterate(val);
}, 0);
}
}
})();
}
Sneak Peak: ES7 Async Functions
async function showFeed(url) {
let data = await request('/feed');
let dom = await feedTemplate.render(data);
document.querySelector('#feed-container').appendChild(dom);
}
showFeed('/feed');
Resources
● David Walsh blog by Kyle Simpson
● Understanding ES6 by Nicholas Zakas

ES6 generators

  • 1.
  • 2.
  • 3.
  • 4.
    Avoid callback inception $el.on('click',function(evt) { $.ajax('/vsearch/pj', function(data) { dust.render('tl/shared/person', data, function (err, out) { $el.html(out); // Please, make it stop! }) }) });
  • 5.
    Example > function *hoover(){ console.log('Preparing to yield "Boulder"'); yield 'Boulder'; console.log('All done yielding'); } > let iter = hoover(); // Nothing happens... > iter.next(); 'Preparing to yield "Boulder"' Object {value: "Boulder", done: false} > iter.next(); 'All done yielding' Object {value: undefined, done: true}
  • 6.
  • 7.
  • 8.
    next() All an objectneeds to be an iterator is a next* method, which returns an object with a value property and a done property. * Iterators generally also include a throw method for throwing errors.
  • 9.
    for … of function*hoover() { console.log('Preparing to yield "Boulder"'); yield 'Boulder'; console.log('All done yielding'); } for (let x of hoover()) { console.log(`x is ${x}`); } // Output: /* Preparing to yield "Boulder" x is Boulder All done yielding */
  • 10.
  • 11.
    Iterables let vals =['a', 'b', 'c']; for (let x of vals) { console.log(`x is ${x}`); } // Output: /* 'a' 'b' 'c' */ // Python lovers rejoice
  • 12.
  • 13.
  • 14.
    Fibonacci Generator function *fibGenerator(){ let prev1 = 1; let prev2 = 0; let current; yield prev2; yield prev1; while (true) { current = prev1 + prev2; prev2 = prev1; prev1 = current; yield current; } }
  • 15.
    Using the FibonacciGenerator var fib = fibGenerator(); console.log(fib.next()); 0 console.log(fib.next()); 1 console.log(fib.next()); 1 console.log(fib.next()); 2 console.log(fib.next()); 3 console.log(fib.next()); 5
  • 16.
  • 17.
    Prompt We already knowhow to pause execution in the middle of a function. function getName() { var name = prompt('What's your name?'); return name; } But now we can pause execution without freezing the entire browser.
  • 18.
  • 19.
    Avoid callback inception $el.on('click',function(evt) { $.ajax('/vsearch/pj', function(data) { dust.render('tl/shared/person', data, function (err, out) { $el.html(out); // Please, make it stop! }) }) }); remember?
  • 20.
    yield is thenew callback function *showFeed() { let data = yield request('/feed'); let dom = yield feedTemplate.render(data); document.querySelector('#feed-container').appendChild(dom); } // To use runMyGenerator(showFeed);
  • 21.
    Behind the Scenes- request function request(url) { if (cachedResponses[url]) { return cachedResponses[url]; } else { return Promise(function(resolve, reject) { makeAjaxRequest(url, resolve); }); } }
  • 22.
    Behind the Scenes- runMyGenerator function runMyGenerator(gen) { let iter = gen(); let yielded; (function iterate(val) { yielded = iter.next(val); if (!yielded.done) { if ('then' in yielded.value) { // Wait for the promise to resolve before the next iteration yielded.value.then(iterate); } else { // Next setTimeout(function() { iterate(val); }, 0); } } })(); }
  • 23.
    Sneak Peak: ES7Async Functions async function showFeed(url) { let data = await request('/feed'); let dom = await feedTemplate.render(data); document.querySelector('#feed-container').appendChild(dom); } showFeed('/feed');
  • 24.
    Resources ● David Walshblog by Kyle Simpson ● Understanding ES6 by Nicholas Zakas