in node.js, how to use bluebird promise with a for

2019-07-23 22:44发布

问题:

I'm using bluebird to make my js code synchronous. When in a for-loop, I don't know the syntax to synchronize it.

for (i=0; i < rows.length; ++i) {
    var writeBuffer = new Buffer(JSON.stringify(rows[i]))
    fs.appendFileAsync(filename, i + '');
}
fs.appendFileAsync(filename, 'end');

I don't know how to make sure that every appendFileAsync takes place in order, and to make sure to append 'end' after the for-loop. Anyone can help me?

回答1:

Try this:

rows.reduce(function(previous, item){
  return previous.then(function(){
    return fs.appendFileAsync(filename, item + '\n');
  });
}, Promise.resolve())
.then(function(){
  fs.appendFileAsync(filename, 'end');
});

Reference: https://stackoverflow.com/a/17764496/1807881

The idea is to chain the promises for each item in the array so they execute in order. With reduce you can grab the previous promise and chain it with the next item in the array using then.



回答2:

You can use array reduce, but for this situation you might not want to consildate your data before making any fs calls.

With array reduce:

  var Promise = require('bluebird');
  var fs = Promise.promisifyAll(require('fs'));

  rows.map(function(row) {
    return new Buffer(JSON.stringify(row));
  }).concat(['end'])
    .reduce(function(a, b) {
      return a.then(function() {
          return fs.appendFileAsync(filename, b);
        })
    }, Promise.resolve(''))
    .then(function(res) {
      // all done here
    })
    .catch(function(err) {
      throw err;
    });

In my opinion the following would be just fine

  var data = rows.map(function(row) {
    return JSON.stringify(row);
  })
  .concat(['end'])
  .join('');

  fs.appendFileAsync(filename, data).then(function(res) {

  });

Once you create a promise, its going. Array reduce is a good way to ensure sequential execution. You are essentially building a chain of promises. In your situation it would work, but is it the best call? Thats going to be a fs call for each row and added complexity to the operation.