2015-06-28 2 views
2

Я использую bluebird, чтобы сделать мой js-код синхронным. Когда в for-loop я не знаю синтаксиса, чтобы его синхронизировать.в node.js, как использовать обещание bluebird с for-loop

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

Я не знаю, как убедиться в том, что каждый appendFileAsync происходит в порядке, и убедиться в том, чтобы добавить «конец» после для петли. Кто-нибудь может мне помочь?

+1

Почему вы создаете 'writeBuffer'? Вы, кажется, не используете его вообще. Вы хотите записать его в файл? – jfriend00

ответ

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

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

+1

Вы можете избежать 'rows.shift()' (и заставить скрипт работать с пустым массивом), запустив накопитель с 'Promise.resolve()' вместо этого 'first' call – Bergi

+0

Спасибо! обновленный ответ. – hassansin

+0

Спасибо! любите это решение. –

0

Вы можете использовать уменьшение массива, но для этой ситуации вы можете не захотеть сортировать свои данные перед выполнением любых вызовов 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-вызов для каждой строки и добавлена ​​сложность операции.

Смежные вопросы