2015-04-05 95 views
1

我想知道在一個請求中創建/更新多個記錄的最佳做法是什麼。我知道我們可以使用Promise.all()來做到這一點。但是如果我想告訴客戶哪些記錄成功了,哪些失敗了怎麼辦?用Sails.js中的一個請求創建/更新多個記錄

例如,用戶交一樣的東西:

{ 
    departmentId: 1, 
    students: [ 
        {name: 'John', studentId: 123}, 
        {name: 'Mike', studentId: 124}, 
       ] 
} 

而我目前的解決方案是:

StudentController:

var departmentId = req.param('departmentId'); 
var postStudents = req.param['students']; 

var department; 
var failedRecords = []; 
Department.findOne() 
    .then(function (_department) { 
     department = _department; 
     var students = []; 
     while (postStudents.length) { 
      var student = postStudents.pop(); 
      student.department = departmentId; 
      var s = Student.create(s) 
         .then(function(s){return s;}) 
         .catch(function(e){ failedRecords.push(student)}); // A closure problem happens here 
      students.push(s); 
     } 
     return students; 
    }) 
    .each(function (student) { 
     department.students.add(student[0].id); 
     return department.save().catch(function(e){/* log: add to department failed */}); 
    }) 
    .then(function() { 
     return res.json({msg: "Success"}); 
    }) 
    .catch(function (e) { 
     return res.json(404, {err: "Fail", records: failedRecords}); 
    }); 

的代碼是醜,我也忽略代碼解決while循環中的閉包問題。另外,我不知道如何保存到第二個catch中的failedRecords。

回答

1

我猜Sails使用Q庫。如果不是,您可以使用Q.()將任何承諾轉換爲Q.

因此,而不是Q.all()方法,你見過Q.allSettled()

下面是從兩種方法(from the Q library guide)之差:

的所有函數返回值的陣列的承諾。當這個承諾被履行時,數組包含原始承諾的履行價值,與承諾的順序相同。如果某個給定的承諾被拒絕,則返回的承諾立即被拒絕,而不是等待批處理的其餘部分。如果你想等待所有的承諾被履行或拒絕,你可以使用allSettled。

Q.allSettled()將等待所有承諾才能完成,即使一個或多個被拒絕,並返回對象的數組,如: { state: "fulfilled", value: v } or { state: "rejected", reason: r }

API Reference - promise.allSettled()

我不知道,如果這是插入數據庫的最佳做法,因爲水線可能有批量插入模式。但是我已經以這種方式完成了發佈到API以插入記錄併爲我工作的很好。

+0

sails.js使用藍鳥,而不是Q. – 2015-04-05 20:09:48

+0

嗨圖利奧,這正是我想要的。但是我在Bluebird中找不到這個:-( – Utility 2015-04-07 09:22:29

+0

在bluebird中,'.allSettled'就是所謂的'.settle' – 2015-04-08 03:35:15

3

您應該可以簡單地運行以下內容來爲學生生成記錄。有關更多信息,請參閱waterline-orm/models/create

// create the students 
var students = [{name: 'John', studentId: 123},{name: 'Mike', studentId: 124}]; 
Student.create(students).exec(function createCB(err, created){ 
    console.log('Created student with name ' + created[0].name); 
    console.log('Created student with name ' + created[1].name); 
    //Do other stuff here. 
});