Running Generators

In Chapter 4, we derived a utility called run(..) which can run generators to completion, listening for yielded Promises and using them to async resume the generator. asynquence has just such a utility built in, called runner(..).

Let’s first set up some helpers for illustration:

  1. function doublePr(x) {
  2. return new Promise( function(resolve,reject){
  3. setTimeout( function(){
  4. resolve( x * 2 );
  5. }, 100 );
  6. } );
  7. }
  8. function doubleSeq(x) {
  9. return ASQ( function(done){
  10. setTimeout( function(){
  11. done( x * 2)
  12. }, 100 );
  13. } );
  14. }

Now, we can use runner(..) as a step in the middle of a sequence:

  1. ASQ( 10, 11 )
  2. .runner( function*(token){
  3. var x = token.messages[0] + token.messages[1];
  4. // yield a real promise
  5. x = yield doublePr( x );
  6. // yield a sequence
  7. x = yield doubleSeq( x );
  8. return x;
  9. } )
  10. .val( function(msg){
  11. console.log( msg ); // 84
  12. } );

Wrapped Generators

You can also create a self-packaged generator — that is, a normal function that runs your specified generator and returns a sequence for its completion — by ASQ.wrap(..)ing it:

  1. var foo = ASQ.wrap( function*(token){
  2. var x = token.messages[0] + token.messages[1];
  3. // yield a real promise
  4. x = yield doublePr( x );
  5. // yield a sequence
  6. x = yield doubleSeq( x );
  7. return x;
  8. }, { gen: true } );
  9. // ..
  10. foo( 8, 9 )
  11. .val( function(msg){
  12. console.log( msg ); // 68
  13. } );

There’s a lot more awesome that runner(..) is capable of, but we’ll come back to that in Appendix B.