в node.js, как использовать обещание bluebird с циклом for

Я использую 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. Кто-нибудь может мне помочь?


person Kingston Chan    schedule 28.06.2015    source источник
comment
Почему вы создаете writeBuffer? Вы, кажется, не используете его вообще. Вы хотите записать это в файл?   -  person jfriend00    schedule 28.06.2015


Ответы (2)


Попробуй это:

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

Идея состоит в том, чтобы связать промисы для каждого элемента в массиве, чтобы они выполнялись по порядку. С помощью reduce вы можете получить предыдущее обещание и связать его со следующим элементом в массиве, используя then.

person hassansin    schedule 28.06.2015
comment
Вы можете избежать rows.shift() (и заставить скрипт работать с пустыми массивами), запустив аккумулятор с Promise.resolve() вместо этого вызова first - person Bergi; 29.06.2015
comment
Благодарю вас! люблю это решение. - person Kingston Chan; 30.06.2015

Вы можете использовать уменьшение массива, но в этой ситуации вы можете не захотеть консолидировать свои данные перед выполнением каких-либо вызовов fs.

С уменьшением массива:

  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) {

  });

Как только вы создаете обещание, оно выполняется. Сокращение массива — хороший способ обеспечить последовательное выполнение. По сути, вы строите цепочку обещаний. В вашей ситуации это сработало бы, но лучший ли это колл? Это будет вызов fs для каждой строки и усложнит операцию.

person undefined    schedule 28.06.2015