Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Meetup.js - ES6 Generators

Meetup.js - ES6 Generators

An Introduction to ES6 Generators.

Check the updated online version:
https://codekult.github.io/meetup-js-generators/

Diego Calderón

July 28, 2015
Tweet

More Decks by Diego Calderón

Other Decks in Technology

Transcript

  1. Hi, I'm Diego Calderón I work @ MercadoLibre, in MercadoShops

    dpt. We gonna talk about generators in ES6 EcmaScript2015. So let’s start…
  2. Generators are a new type of function which can be

    paused and resumed. Breaking the run-to-completion behavior.
  3. Generators are declared as regular functions but in the following

    manner: f u n c t i o n * m y G e n ( ) { . . . } / / O r t h e s a m e ` f u n c t i o n * m y G e n ( ) { . . . } `
  4. We can argue about how to write a generator signature,

    but only when we finished the tabs vs spaces talk.
  5. Also the y i e l d keyword is introduced,

    and we’ll use as a mark for pause/restart the generator and as a way to send and receive data.
  6. f u n c t i o n * m

    y G e n ( ) { c o n s o l e . l o g ( ' H i ' ) ; y i e l d ; c o n s o l e . l o g ( ' B y e ' ) ; } v a r o b j G e n = m y G e n ( ) ; o b j G e n . n e x t ( ) ; / / ' H i ' o b j G e n . n e x t ( ) ; / / ' B y e '
  7. A benefit of generators is its synchronous like semantics, so

    we can use ol’ t r y { . . . } c a t c h ( e r r ) { } to handle errors.
  8. f u n c t i o n * m

    y G e n ( ) { t r y { v a r n u m b e r = 3 ; y i e l d ; c o n s o l e . l o g ( n u m b e r . t o U p p e r C a s e ( ) ) ; } c a t c h ( e r r ) { c o n s o l e . e r r o r ( e r r ) ; } } v a r o b j G e n = m y G e n ( ) ; o b j G e n . n e x t ( ) ; o b j G e n . n e x t ( ) ; Online example
  9. We can include a generator inside another generator using a

    y i e l d variation: y i e l d * . The nesting levels are infinite.
  10. f u n c t i o n * i

    n n e r G e n ( ) { y i e l d c o n s o l e . l o g ( 2 ) ; y i e l d c o n s o l e . l o g ( 3 ) ; y i e l d c o n s o l e . l o g ( 4 ) ; } f u n c t i o n * o u t e r G e n ( ) { y i e l d c o n s o l e . l o g ( 1 ) ; y i e l d * i n s i d e G e n ( ) ; / / O r t h e s a m e y i e l d * i n s i d e G e n ( ) ; y i e l d c o n s o l e . l o g ( 5 ) ; } Online example
  11. Every time we’re using a generator like this: / /

    G i v e n a ´ m y G e n ´ g e n e r a t o r f u n c t i o n v a r o b j G e n = m y G e n ( ) ;
  12. We’re creating an iterator object, which we assign to the

    variable o b j G e n , to control * m y G e n ( ) generator.
  13. We can use the i t e r a b

    l e interface to control the iterator, which counts with methods as n e x t ( ) , r e t u r n ( ) or t h r o w ( ) .
  14. Another benefits of i t e r a b l

    e s is that them can be consumed by data consumers as f o r … o f loops, the s p r e a d operator and can be used in array destructuring.
  15. Calling . n e x t on an iterable gives

    us an object containing a value, or an indication that there are no further values.
  16. v a r m y A r r = [

    1 , 2 , 3 ] , m y A r r I t = m y A r r [ S y m b o l . i t e r a t o r ] ( ) ; m y A r r I t . n e x t ( ) ; / / O b j e c t { v a l u e : 1 , d o n e : f a l s e } m y A r r I t . n e x t ( ) ; / / O b j e c t { v a l u e : 2 , d o n e : f a l s e } m y A r r I t . n e x t ( ) ; / / O b j e c t { v a l u e : 3 , d o n e : f a l s e } m y A r r I t . n e x t ( ) ; / / O b j e c t { v a l u e : u n d e f i n e d , d o n e : t r u e }
  17. Each y i e l d can return a value

    via n e x t ( ) . Which means that generators can produce sequences of values via loops and recursion.
  18. Return values with y i e l d y i

    e l d can return a value to the generator caller.
  19. f u n c t i o n * m

    y G e n ( x ) { v a r s i n g l e = y i e l d x , d o u b l e = y i e l d ( x * 2 ) , t r i p l e = y i e l d ( x * 3 ) ; } v a r o b j G e n = m y G e n ( 4 ) ; c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 4 c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 8 c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 1 2 Online Example
  20. Using r e t u r n inside generators We

    can achieve the later example using r e t u r n .
  21. f u n c t i o n * m

    y G e n ( x ) { v a r s i n g l e = y i e l d x , d o u b l e = y i e l d ( x * 2 ) , t r i p l e = x * 3 ; r e t u r n t r i p l e ; } v a r o b j G e n = m y G e n ( 4 ) ; c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 4 c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 8 c o n s o l e . l o g ( o b j G e n . n e x t ( ) . v a l u e ) ; / / 1 2 Online example
  22. Also we can use r e t u r n

    with delegated generators. Let’s see an Online example
  23. Given a generator as the following: f u n c

    t i o n * m y G e n ( ) { y i e l d 1 ; y i e l d 2 ; y i e l d 3 ; }
  24. Using f o r … o f loops: f o

    r ( l e t n o f m y G e n ( ) ) { c o n s o l e . l o g ( n ) ; / / 1 , 2 , 3 } Online example
  25. Using s p r e a d operator: l e

    t m y A r r = [ . . . m y G e n ( ) ] ; / / [ 1 , 2 , 3 ] Online example
  26. Destructuring : l e t [ a , b ,

    . . . r e s t ] = m y G e n ( ) ; / / [ 1 , 2 , 3 ] Online example
  27. y i e l d can also receive a value

    from n e x t ( ) . That means that generator become a data consumer that pause itself until a new value is pushed into it.
  28. There are three ways of sending data to the generator:

    via n e x t ( ) , r e t u r n ( ) , or t h r o w ( ) .
  29. Sending data via n e x t ( ) :

    f u n c t i o n * m y G e n ( ) { c o n s o l e . l o g ( ' S t a r t e d … ' ) ; v a r d o u b l e = ( y i e l d ) * 2 , t r i p l e = ( y i e l d ) * 3 ; c o n s o l e . l o g ( d o u b l e ) ; c o n s o l e . l o g ( t r i p l e ) ; } v a r o b j G e n = m y G e n ( ) ; o b j G e n . n e x t ( ) ; / / S t a r t g e n e r a t o r o b j G e n . n e x t ( 5 ) ; / / 1 0 o b j G e n . n e x t ( 3 ) ; / / 9
  30. Terminating the generator via r e t u r n

    ( ) : f u n c t i o n * m y G e n ( ) { c o n s o l e . l o g ( ' S t a r t e d … ' ) ; y i e l d ; / / I n s e r t s a ` r e t u r n ` a t t h i s p o i n t c o n s o l e . l o g ( ' N e v e r g e t s h e r e ' ) ; } v a r o b j G e n = m y G e n ( ) ; o b j G e n . n e x t ( ) ; c o n s o l e . l o g ( o b j G e n . r e t u r n ( ' … T h i s i s t h e e n d . ' ) . v a l u e ) ; Online example
  31. Throwing errors via t h r o w ( )

    : f u n c t i o n * m y G e n ( ) { t r y { c o n s o l e . l o g ( ' S t a r t e d … ' ) ; y i e l d ; / / T h r o w s e r r o r a t t h i s p o i n t c o n s o l e . l o g ( ' N e v e r g e t s h e r e ' ) ; } c a t c h ( e r r ) { c o n s o l e . e r r o r ( ` E r r o r : $ { e r r } ` ) ; } } v a r o b j G e n = m y G e n ( ) ; o b j G e n . n e x t ( ) ; o b j G e n . t h r o w ( ' A n e r r o r o c u r r e d ' ) ; Online example
  32. Now we can apply these behaviours in a combined way

    to create new patterns, as cooperative tasks, mimic coroutines or applying complex techniques as CSP.
  33. Also we can apply this pattern to asynchronous operations to

    get the maximun benefit from generators capabilities.
  34. We can use y i e l d for waiting

    for a promise, and making that the promise itself resume the generator flow when it’s resolved.
  35. This allow us to write more readable and maintenable code,

    which looks synchonous like, hiding away the async implementations.
  36. The previous pattern is very useful. And is included in

    the ES7 EcmaScript2016 specification as a s y n c functions.
  37. We can use an a s y n c function

    as follow: a s y n c f u n c t i o n ( ) { t r y { l e t r e q = a w a i t r e q u e s t ( h t t p : / / s o m e u r l . c o m / g e t C o n t e n t ) ; / / P r o m i s / / D o s o m e t i n g w i t h ` r e q ` } c a t c h ( e r r ) { c o n s o l e . e r r o r ( e r r ) ; } }
  38. and by @ rauschma. by @ jaffathecake. and by @getify.

    by @jhusain. Iterables and Iterators ES6 Generators in depth Iterators gonna iterate ES6 Generators (serie) YDKJS: Async and Performance Async Programming in ES7
  39. Q&A