2016-12-13 1 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

이제는 어떻게 작동합니까? [Code Review] (http://codereview.stackexchange.com/)에 게시 할 가치가 있습니다. –

+0

이것은 필요한 것을 얻기위한 합리적인 방법입니다. 반복을 줄이려면 약속 체인의 끝에있는 'finally'호출에 전체 체크를 넣고'then'과'catch' 핸들러에서 그것을 제거 할 수 있습니다. –

+0

감사합니다. 나는 자바 스크립트를 처음 사용하고 이것이 올바른지 확실하지 않았다. @JordanBurnett 코드를 DRY로 유지 보수 할 것입니다. – 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를 반환으로 병렬로 db.List.create()를 실행하는 Promise.all()를 사용하여 다음과 같은 방법을 추천 할 것입니다. 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)); 
} 
관련 문제