如何避免在使用q.map时破坏承诺链?

我想我可能已经过于乐观了。 我有一堆鹅,在返回最终值之前,我想要执行任意数量的操作。 我发现,在第一个回报声明之后,链条被打破了。 如果我的集合有10个项目,那么将有10个项目被放置在数据库中,但是当我尝试从下面的“return Q.all(promises)”语句构buildAPI响应时,我会得到空值。

为了testing,我已经把一个console.log语句放在一个承诺之后,在我的expressjs路由里面的第一个和一个console.log之后触发,它期待着鹅的细节。 API响应总是首先完成“[null,null]”,然后最终获得链中第二个和第三个promise的条目。

我是如何创造这种竞争条件的,我该如何解决?

var promises = geese.map(function(goose) { determineGooseType(goose.details) .then(function(type) { return recordNewGooseType(type) }) .then(function(dbInsertResult) { we never really got here! }) .catch(function(err) { log some stuff }); } return Q.all(promises); 

你没有一个承诺的数组,你有一个undefined值数组( Q.all没有警告你):你的映射函数不返回任何东西。 你错过了一个return语句:

 var promises = geese.map(function(goose) { return determineGooseType(goose.details) //^^^^^^ .then(function(type) { return recordNewGooseType(type) }) .then(function(dbInsertResult) { // now getting here before resolving the .all() promise! }) .catch(function(err) { log some stuff }); } return Q.all(promises); 

这意味着有两个select:

recordNewGooseType不正确地promisified或determineGooseType GooseType是。 具体来说 – 因为你说的API响应determineGooseType recordNewGooseType返回[null, null]唯一合理的假设是recordNewGooseType是责备。

这意味着promisified recordNewGooseType不能调用resolve

您可以通过在一只鹅上运行而不是在10只鹅上进行validation。