2016-12-13 53 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)); 
}