richb-hanover

Combining asynquence sequences

Feb 10th, 2016
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Combining sequences with asynquence - https://github.com/getify/asynquence
  2. //
  3. // This code was prepared as an answer to https://github.com/getify/asynquence/issues/84
  4. // It is a skeleton of working code that shows how to make various sequences interact.
  5. //
  6. //  There are four functions:
  7. //  - DoSomethingUseful() gets called when it's time to update some data structure.
  8. //      To make its update, it calls SendCommand() to request some data, which it then uses.
  9. //  - SendCommand() is also a sequence. It calls Connect() to establish a connection
  10. //      then sends a command and waits for the response to return.
  11. //  - Connect() is another sequence. It checks to see if a connection has already been
  12. //      established, in which case, it returns to complete the caller's step.
  13. //      Otherwise, it establishes the connection and then returns/completes the step
  14. //  - tlsConnect() shows how to handle a non error-first callback, and also provides
  15. //      an example of using the node tls connection with asynquence
  16. //
  17. // NOTE: THIS CODE DOES NOT WORK. It is only schematic, but gives the flavor of using asynquence
  18. // 16 Feb 2016 - www.richb-hanover.com
  19. // ===========================================================================
  20.  
  21. ASQ = require("asynquence");
  22.  
  23. /*
  24.  * DoSomethingUseful() is a sequence that calls SendCommand() to
  25.  *  send a request and return its response. It uses that response to do
  26.  *  something useful in the program.
  27.  */
  28. function DoSomethingUseful() {
  29.  
  30. ASQ()                                               // create an empty sequence
  31.   .then((done) => {
  32.     SendCommand(done, "ThisIsACommand");            // SendCommand() calls the done trigger when it completes
  33.   })
  34.   .then((done, response) => {                       // response comes from SendCommand()'s response
  35.     //... some code to use 'response' ...           // use the response in some useful way      
  36.     done();                                         // call done() to indicate the end of DoSomethingUseful()
  37.   })
  38.   .or((err) => {                                    // or handle the error
  39.     console.log(`Yikes! Something bad happened: ${err}`);
  40.   })
  41. }
  42.  
  43. /*
  44.  * SendCommand(fndone, cmd) - starts a sequence, sends a command and waits for the response
  45.  *    fndone is the done trigger that indicates SendCommand() has completed
  46.  */
  47.  
  48. function SendCommand(fndone, cmd) {                       // fndone is the trigger that completes the *caller's* step
  49.  
  50.   var eventName;
  51.  
  52.   ASQ()                                                   // Create an empty sequence
  53.     .then((done) => {
  54.       Connect(done)                                       // Call Connect() - when it finishes, it calls done()
  55.       })                                                  //   to move to the next step of this sequence
  56.     .then((done) => {
  57.       writeCommand(cmd, svr);                             // Now that connection is established, write command to other end
  58.                  
  59.       EventEmitter.once(eventName,(resp) => {             // In this example, an 'eventName' event indicates a response has arrived
  60.         done(resp);                                       // done(resp) indicates the end of *this step* and passes on the response
  61.         });                                                
  62.       })
  63.     .then((done, resp) => {                               // resp is the response from previous step
  64.       fndone(resp)                                        // fndone(resp) returns the response and
  65.       })                                                  //    indicates that the *function* is done
  66.     .or((err) => {
  67.       console.log(`Yikes! Command error '${err}'`);       // .or(err) handles error cases...
  68.       });
  69. }
  70.  
  71. /*
  72.  * Connect(fndone) - establishes a connection.
  73.  *  The first step of the sequence checks to see if the connection is already established
  74.  *    If so, it calls fndone() and returns to its caller
  75.  *    Otherwise, it goes through the steps to establish the connection, then calls fndone()
  76.  */
  77.  
  78. function Connect(fndone) {                                // fndone is the trigger that completes the *caller's* step
  79.  
  80.   ASQ()                                                   // Create an empty sequence
  81.     .then((done) => {                                     // First step - check to see if we're already connected
  82.       if (isConnected()) {
  83.         fndone(svr);                                      // if so, call the *caller's* done trigger
  84.       }
  85.       else {
  86.         done();                                           // otherwise, call the local trigger to end this step
  87.       }
  88.       })
  89.     .then((done) => {                                     // next step - tlsConnect sets up a connection
  90.       tlsConnect(done)                                    // it calls done(svr) to return the connection info
  91.       })                
  92.     .then((done, svr) => {                                // next step - createStream receives svr from previous step
  93.       createStream(done, svr)                             // it calls done() when complete (no info passed to next step)
  94.       })    
  95.     .then((done) => {                                     // next step - log the info
  96.       console.log( "Ended Connect - streams created/connected");
  97.       fndone(svr);                                        // and call the *caller's* trigger - fndone()
  98.       })
  99.     .or((err) => {                                        // or() handles errors
  100.       console.log( "Ended Connect with error: ", err.message);
  101.     });
  102. }
  103.  
  104.  
  105. var tls = require('tls');               // example of non-error-first callback (not an errfcb)
  106. function tlsConnect(done) {             // non-ASQ code
  107.   //...
  108. var svr = tls.connect(                  // the tls.connect() function takes a port, options, and a callback when complete
  109.         tlsPort,                        // your port
  110.         tlsOptions,                     // your options
  111.         () => {                         // the callback
  112.          
  113.           svr.on('close', (err) => {    // set up stream handlers for close and error
  114.             console.log( "TLS stream was closed by other end.", err);
  115.             });
  116.           svr.on('error', (err) => {
  117.             console.log( "TLS stream got error: ", err);
  118.             });
  119.           done(svr);                    // call the done(svr) trigger to pass back the tls stream
  120.           }        
  121. )}
  122.  
  123. function createSaxStream(done, svr) {  // non-ASQ code
  124.   // ...
  125.   done();
  126. }
Advertisement
Add Comment
Please, Sign In to add comment