2014-07-11 2 views
0

시딩 스크립트를 실행하려면 asyncpromise을 사용하고 있지만 모든 약속이 reject 일 경우 스크립트가 완료되지 않습니다.모두 거부 된 비동기 및 약속 사용시 비동기 완료되지 않음

시딩 스크립트이므로 데이터가있는 모델을 시드하지 않도록 설정되었습니다. 여기

내 코드 내가 놓친 한 것을

어떤 생각 (요약 된)이야? 코드에서

seed = function(collectionName, data) { 
    return new Promise(function(fulfill, reject) { 
    var collection = collections[collectionName]; 
    collection.find().exec(function(err, found) { 
     if (found.length > 0) { 
     console.log("There are", found.length, collectionName, "records in the database already."); 
     reject(); 
     } else { 
     collection.createEach(data, function(err, models) { 
      if (err || _.isUndefined(models)) { 
      console.log("Could not create", collectionName, "collection!"); 
      reject(); 
      } else { 
      collection.find().exec(function(err, found) { 
       fulfill(found); 
      }); 
      } 
     }); 
     } 
    }); 
    }); 
}; 

run = function(models, done) { 
    async.each(models, function(modelName, next) { 
    seed(modelName, modelData[modelName]).then(function(codes) { 
     console.log("Seeded", codes.length, modelName, "records."); 
     next(); 
    }, function(err){ 
     console.log("Seeding of", modelName, "failed", err.stack); 
     done(err); 
    }); 
    }, done); 
}; 

run(["widget", "thingo", "dooverlackey"], function(err){ 
    if (err) console.error("Completed with errors", err); 
    else console.log("Completed without errors"); 
    process.exit(); 
}); 
+0

이 또한 오류 메시지를'reject ("my error")'로 전달하면 전체 오류가 내가 원하지 않는 첫 번째 오류에서 멈 춥니 다. 이미 데이터가있는 모델은 건너 뛰기 만하면됩니다. –

+0

약속은 이미 비동기 집계 및 구조화를 제공합니다. 여기 비동기 모듈을 사용할 이유가 없습니다. for 루프에서 비동기 적으로 연결을 간단히'.then' 할 수 있습니다. –

+0

감사합니다. Benjamin - 좋은 지적이지만 async를 사용하면 다른 배열을 배열에 추가 할 수 있습니다. 대신 Promise 구조를 제거하는 대신 사물을 단순화합니다. –

답변

2

, 당신은 seed()에 대한 호출 거부 할 경우, 다음 코드는 done()를 호출하여 .then()의 거부 핸들러로 이동합니다.

seed(modelName, modelData[modelName]).then(function(codes) { 
    console.log("Seeded", codes.length, modelName, "records."); 
    next(); 
}, function(err){ 
    console.log("Seeding of", modelName, "failed", err.stack); 
    // upon fail from seed, stop processing 
    done(err); 
}); 

당신이 할 수있는 처리를 계속하거나, 그래서 당신은 당신의 핸들러 (.then()에 전달 된 두 번째 콜백을) 거부 변경할 수 있습니다 : 그래서, 당신의 자신의 구조는이 코드에서 거절을 얻는 경우에 처리를 중지 할 말있다 계속할 수없는 심각한 오류가있는 경우에만 seed()을 변경하여 거부하십시오.

약속을 사용하는 방법에는 여러 가지가 있지만 심각한 오류의 경우 seed() 기능을 reject()으로 변경하는 것을 계속할 수없는 심각한 오류에 대해서는 거부를 예약하는 것이 더 일반적입니다. 작업이 이미 완료 되었기 때문에 아무 것도 할 수 없다는 것을 발견했을 때, 그냥 resolve() 일 뿐이며 전체 프로세스가 계속 진행됩니다.

관련 문제