2016-12-13 40 views
0

我需要遍历数组并将每个对象保存到数据库。遍历数组并保存对象后回调

最后我需要回调一个array的所有保存和失败的对象。

下面是我的代码:

exports.addList = (app, body, callback) => { 
var savedObjects = [] 
var failedObjects = [] 

body.forEach((element, index) => { 
    body[index] = _.pick(element, 'userAId','userBId') 

    db.List.create(element).then((list) => { 
     savedObjects.push(element) 
     if (index == body.length - 1) { 
      callback(savedObjects, failedObjects) 
     } 
    }).catch((error) => { 
     if (error.name === "SequelizeUniqueConstraintError") { 
      failedObjects.push(element) 
      if (index == body.length - 1) { 
      callback(savedObjects, failedObjects) 
     } 
    }) 
}) 
} 

上述工程的代码。有没有更好的方法来实现这一点?

+0

你不喜欢现在如何工作?它也许值得发布到[代码评论](http://codereview.stackexchange.com/)。 –

+0

这似乎是一种合理的方式来实现你所需要的。如果你想减少一些重复,你可以把你的完整支票放在承诺链末尾的一个'finally'调用中,并将它从'then'和'catch'处理程序中移除。 –

+0

谢谢。我是JavaScript新手,不确定这是否正确。 @JordanBurnett我会重构保持代码干。 – user1107173

回答

0

在您的示例中,您的完整回调将始终在第一个承诺完成后触发。这是因为create函数是异步的,而周围的循环不是,因此在第一次回调被触发时,循环已经完成。

在您的情况下,这意味着elementindex将始终是循环中的最后一个。解决这个问题的一个方法是将您的承诺链转变为自己的功能。

在这个例子中,我使用了一个额外的标志来跟踪已完成的承诺数量,以触发您的complete方法。

exports.addList = (app, body, callback) => { 
    var savedObjects = [] 
    var failedObjects = [] 
    var complete = 0; 

    function createElement(element){ 
    db.List.create(element).then((list) => { 
     savedObjects.push(element) 
    }).catch((error) => { 
     if (error.name === "SequelizeUniqueConstraintError") { 
      failedObjects.push(element) 
     } 
    }).finally(() => { 
     complete++; 
     if(complete == body.length) { 
      callback(savedObjects, failedObjects) 
     } 
    }); 
    } 

    body.forEach((element, index) => { 
    body[index] = _.pick(element, 'userAId','userBId'); 
    createElement(element); 
    }) 
} 
+0

如果你希望'db.List.create()'并行运行,你也可以在'Promise.all()。then()'中做到这一点。 – doublesharp

1

我会建议使用Promise.all()并行运行db.List.create(),因为它会返回一个Promise以下办法。通过mappingbody数组元素到Promises您可以实现更好的性能,因为它们将并行运行(而不必跟踪complete计数)。

exports.addList = (app, body, callback) => { 
    var savedObjects = []; 
    var failedObjects = []; 

    Promise.all(
    // map the array to return Promises 
    body.map(element => { 
     const list = _.pick(element, 'userAId','userBId'); 
     return db.List.create(list) 
     .then(() => savedObjects.push(list)) 
     .catch((error) => { 
     if (error.name === 'SequelizeUniqueConstraintError') { 
      failedObjects.push(list) 
     } 
     }) 
    }) 
) 
    // when all Promises have resolved return the callback 
    .then(() => callback(savedObjects, failedObjects)); 
}