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

Generator与异步编程

 Generator与异步编程

from:denghongqi

baidu-efe-ares

August 15, 2014
Tweet

More Decks by baidu-efe-ares

Other Decks in Technology

Transcript

  1. ES6 --HARMONY ES.next(Ecma-262 Edition 6): ECMAScript Wiki Default Parameters Rest

    Parameters Sets Maps Iterators Generators Proxy Arrow Functions Modules ...
  2. GENERATOR OVERVIEW 生成器是一种特殊的函数, 它可以在执行几步操作后先行退出, 然后在需要的时候进入函数内部继续执 行. 函数的上下文(变量绑定等信息)会始终保留. f u n

    c t i o n * i d M a k e r ( ) { v a r i n d e x = 0 ; w h i l e ( t r u e ) y i e l d i n d e x + + ; } v a r g e n = i d M a k e r ( ) ; c o n s o l e . l o g ( g e n . n e x t ( ) . v a l u e ) ; / / 0 c o n s o l e . l o g ( g e n . n e x t ( ) . v a l u e ) ; / / 1 c o n s o l e . l o g ( g e n . n e x t ( ) . v a l u e ) ; / / 2
  3. YIELD A s s i g n m e n

    t E x p r e s s i o n : . . . Y i e l d E x p r e s s i o n Y i e l d E x p r e s s i o n : " y i e l d " ( " * " ? A s s i g n m e n t E x p r e s s i o n ) ? yield 和 yield * 为一元操作符,仅可以用于Generator内部。 yield * 与yield的区别是yield *显式地声明 AssignmentExpression是一个Generation,功能同yield yield 可以中断Generator的执行,并返回 AssignmentExpression
  4. 举个栗子 f u n c t i o n *

    G e n A ( ) { c o n s o l e . l o g ( ' f r o m G e n A , f i r s t . ' ) ; y i e l d 1 ; c o n s o l e . l o g ( ' f r o m G e n A , s e c o n d . ' ) ; v a r v a l u e 3 = y i e l d 2 ; c o n s o l e . l o g ( ' f r o m G e n A , t h i r d . ' , v a l u e 3 ) ; r e t u r n 3 ; } v a r a = n e w G e n A ( ) ;
  5. 执行结果 a . n e x t ( ) ;

    / / f r o m G e n A , f i r s t . / / O b j e c t { v a l u e : 1 , d o n e : f a l s e } a . n e x t ( ) ; / / f r o m G e n A , s e c o n d . / / O b j e c t { v a l u e : 2 , d o n e : f a l s e } a . n e x t ( 3 3 3 ) ; / / f r o m G e n A , t h i r d . / / 3 3 3 / / O b j e c t { v a l u e : 3 , d o n e : t r u e } a . n e x t ( ) ; / / E r r o r : G e n e r a t o r h a s a l r e a d y f i n i s h e d
  6. 异步串行读取文件 f s . r e a d F i

    l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' , f u n c t i o n ( e r r , t x t ) { i f ( e r r ) { t h r o w e r r ; } f s . r e a d F i l e ( t x t , ' u t f 8 ' , f u n c t i o n ( e r r , c o n t e n t ) { i f ( e r r ) { t h r o w e r r ; } c o n s o l e . l o g ( c o n t e n t ) ; } ) ; } ) ;
  7. 异步并行读取文件 f s . r e a d F i

    l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' , f u n c t i o n ( e r r , t x t ) { i f ( e r r ) { t h r o w e r r ; } c o n s o l e . l o g ( t x t ) ; } ) ; f s . r e a d F i l e ( ' f i l e 2 . t x t ' , ' u t f 8 ' , f u n c t i o n ( e r r , c o n t e n t ) { i f ( e r r ) { t h r o w e r r ; } c o n s o l e . l o g ( c o n t e n t ) ; } ) ;
  8. 用GENERATOR实现异步串行读取文件 v a r f l o w = f

    u n c t i o n * ( ) { v a r t x t = y i e l d f s . r e a d F i l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' ) ; v a r c o n t e n t = y i e l d f s . r e a d F i l e ( t x t , ' u t f 8 ' ) ; c o n s o l e . l o g ( c o n t e n t ) ; } ; 需要在回掉函数执行的时候触发这个Generator执行一 次.next(),然后将返回结果通过.next(result)的形式传入
  9. 改造异步方法 v a r h e l p e r

    = f u n c t i o n ( f n ) { r e t u r n f u n c t i o n ( ) { v a r a r g s = [ ] . s l i c e . c a l l ( a r g u m e n t s ) ; v a r p a s s ; a r g s . p u s h ( f u n c t i o n ( ) { / / 在回调函数中植入收集逻辑 i f ( p a s s ) { p a s s . a p p l y ( n u l l , a r g u m e n t s ) ; } } ) ; f n . a p p l y ( n u l l , a r g s ) ; r e t u r n f u n c t i o n ( f n ) { / / 传入一个收集函数 p a s s = f n ; } ; } ; } ;
  10. 改造异步方法 v a r r e a d F i

    l e = h e l p e r ( f s . r e a d F i l e ) ; / / = > / / f u n c t i o n ( ) { / / v a r a r g s = [ ] . s l i c e . c a l l ( a r g u m e n t s ) ; / / v a r p a s s ; / / a r g s . p u s h ( f u n c t i o n ( ) { / / 在回调函数中植入收集逻辑 / / i f ( p a s s ) { / / p a s s . a p p l y ( n u l l , a r g u m e n t s ) ; / / } / / } ) ; / / f n . a p p l y ( n u l l , a r g s ) ; / / / / r e t u r n f u n c t i o n ( f n ) { / / 传入一个收集函数 / / p a s s = f n ; / / } ; / / } v a r f l o w = f u n c t i o n * ( ) { v a r t x t = y i e l d r e a d F i l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' ) ; c o n s o l e . l o g ( t x t ) ; } ; v a r g e n e r a t o r = f l o w ( ) ; v a r r e t = g e n e r a t o r . n e x t ( ) ; / / 执行r e a d F i l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' ) ; / / r e t . v a l u e = > / / f u n c t i o n ( f n ) { / / p a s s = f n ; / / }
  11. 完整的异步调用代码 v a r g e n e r a

    t o r = f l o w ( ) ; v a r r e t = g e n e r a t o r . n e x t ( ) ; / / 执行r e a d F i l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' ) ; r e t . v a l u e ( f u n c t i o n ( e r r , d a t a ) { i f ( e r r ) { t h r o w e r r ; } g e n e r a t o r . n e x t ( d a t a ) ; } ) ;
  12. 设计流程控制函数 v a r c o = f u n

    c t i o n ( f l o w ) { v a r g e n e r a t o r = f l o w ( ) ; v a r n e x t = f u n c t i o n ( d a t a ) { v a r r e s u l t = g e n e r a t o r . n e x t ( d a t a ) ; i f ( ! r e s u l t . d o n e ) { r e s u l t . v a l u e ( f u n c t i o n ( e r r , d a t a ) { i f ( e r r ) { t h r o w e r r ; } n e x t ( d a t a ) ; } ) ; } } ; n e x t ( ) ; } ;
  13. 调用示例 c o ( f u n c t i

    o n * ( ) { v a r t x t = y i e l d r e a d F i l e ( ' f i l e 1 . t x t ' , ' u t f 8 ' ) ; c o n s o l e . l o g ( t x t ) ; v a r t x t 2 = y i e l d r e a d F i l e ( ' f i l e 2 . t x t ' , ' u t f 8 ' ) ; c o n s o l e . l o g ( t x t 2 ) ; } ) ;
  14. Q&A