在node.js中,如何使用for循环的bluebird promise

时间:2015-06-28 20:09:57

标签: node.js for-loop promise

我正在使用bluebird使我的js代码同步。在for循环中,我不知道同步它的语法。

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

我不知道如何确保每个appendFileAsync按顺序发生,并确保在for循环后追加'end'。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:3)

试试这个:

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

参考:https://stackoverflow.com/a/17764496/1807881

这个想法是链接数组中每个项目的promise,以便它们按顺序执行。使用reduce,您可以使用then获取先前的承诺并将其与数组中的下一个项链接起来。

答案 1 :(得分:0)

您可以使用array reduce,但在这种情况下,您可能不希望在进行任何fs调用之前建立数据。

使用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;
    });

在我看来,以下情况会很好

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

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

  });

一旦你创造了一个承诺,它就会发展。 Array reduce是确保顺序执行的好方法。你本质上是在构建一系列承诺。在你的情况下它会工作,但它是最好的电话吗?这将成为每一行的fs调用,并增加了操作的复杂性。