用Sails.js中的一个请求创建/更新多个记录

问题描述:

我想知道在一个请求中创建/更新多个记录的最佳做法是什么。我知道我们可以使用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。

我猜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

您应该可以简单地运行以下内容来为学生生成记录。有关更多信息,请参阅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. 
});