ใน node.js วิธีใช้สัญญา bluebird กับ for-loop

ฉันใช้ bluebird เพื่อทำให้โค้ด js ของฉันซิงโครนัส เมื่ออยู่ใน 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 เกิดขึ้นตามลำดับ และเพื่อให้แน่ใจว่าได้ต่อท้าย 'end' หลัง for-loop ใครสามารถช่วยฉันได้บ้าง?


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