es6 generators

24
ES6 Generators

Upload: steven-foote

Post on 06-Aug-2015

152 views

Category:

Technology


6 download

TRANSCRIPT

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 … offunction *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

Iterableslet 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

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 callbackfunction *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 - runMyGeneratorfunction 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');