简体   繁体   中英

Using promises to execute a series of commands in nodejs

I want to process a series of commands step by step via serial line in nodejs by using Q promises.

var cmdArr = ['cmd1', 'cmd2','cmd3'];

I am not sure how to build this. I thought about something like this but it did not work:

Q().then(function() {
  cmdArr.forEach(command) {
     //here to initialize the promise??
  }
});

Important is to keep the sequence and are able to use Q.delay in between each step.

Assuming that the commands you want to perform are some sort of async function call:

var Q = require('q');

// This is the function you want to perform. For example purposes, all this
// does is use `setTimeout` to fake an async operation that takes some time.
function asyncOperation(input, cb) {
  setTimeout(function() {
    cb();
  }, 250);
};

function performCommand(command) {
  console.log('performing command', command);
  // Here the async function is called with an argument (`command`),
  // and once it's done, an extra delay is added (this could be optional
  // depending on the command that is executed).
  return Q.nfcall(asyncOperation, command).delay(1000);
}

// Set up a sequential promise chain, where a command is executed
// only when the previous has finished.
var chain = Q();
[ 'cmd1', 'cmd2', 'cmd3' ].forEach(function(step) {
  chain = chain.then(performCommand.bind(null, step));
});

// At this point, all commands have been executed.
chain.then(function() {
  console.log('all done!');
});

I'm not overly familiar with q so it may be done better.

For completeness, here's a version using bluebird :

var Promise = require('bluebird');

...

var asyncOperationAsPromised = Promise.promisify(asyncOperation);

function performCommand(command) {
  console.log('performing command', command);
  return asyncOperationAsPromised(command).delay(1000);
}

Promise.each(
  [ 'cmd1', 'cmd2', 'cmd3' ],
  performCommand.bind(null)
).then(function() {
  console.log('all done!');
});

A common design pattern for sequencing a bunch of async operations on an array is to use .reduce() like this:

var cmdArr = ['cmd1', 'cmd2','cmd3'];

cmdArr.reduce(function(p, item) {
    return p.delay(1000).then(function() {
        // code to process item here
        // if this code is asynchronous, it should return a promise here
        return someAyncOperation(item);
    });
}, Q()).then(function(finalResult) {
    // all items done here
});

Note, I've also shown where you can insert Q's .delay() as requested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM