I think I may have gotten too fancy with promises. I have an array of geese, and there's an arbitrary number of operations I would like to perform before returning a final value. I've found that after the first return statement, the chain is broken. If my collection has 10 items, exactly 10 items will be placed in the database, but I get null values when I try to build my API response from the "return Q.all(promises)" statement below.
我想我可能对承诺过于幻想。我有一系列鹅,并且在返回最终值之前我想执行任意数量的操作。我发现在第一个return语句之后,链条被破坏了。如果我的集合有10个项目,那么将在数据库中放置10个项目,但是当我尝试从下面的“return Q.all(promises)”语句构建我的API响应时,我得到空值。
To test, I've put a console.log statement inside a promise that fires after the first one and a console.log inside of my expressjs route which is expecting details on geese. The API response always finishes first "[null, null]" and then eventually I get entries for my 2nd and 3rd promises in the chain.
为了测试,我将一个console.log语句放在一个promise中,该promise在第一个之后触发,而一个console.log在我的expressjs路由中,它正在期待鹅的详细信息。 API响应总是首先完成“[null,null]”,然后我最终获得链中第2和第3个承诺的条目。
How did I create this race condition and how can I fix it?
我是如何创建这种竞争条件的,我该如何修复它?
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);
2 个解决方案
#1
1
You don't have an array of promises, you have an array of undefined
values (and Q.all
didn't warn you about it): Your mapper function is not returning anything. You're missing a return
statement there:
你没有一个promises数组,你有一个未定义值的数组(并且Q.all没有警告你):你的mapper函数没有返回任何东西。你错过了那里的退货声明:
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);
#2
1
This means there are two options:
这意味着有两种选择:
Either recordNewGooseType
is promisified incorrectly or determineGooseType
is. Specifically - since you said the API response determineGooseType
returns [null, null]
the only reasonable assumption is that recordNewGooseType
is to blame.
recordNewGooseType被错误地宣告或者确定GooseType是。具体来说 - 既然你说API响应confirmGooseType返回[null,null],那么唯一合理的假设就是责备recordNewGooseType。
This means that the promisified recordNewGooseType
is not calling resolve
.
这意味着promisified recordNewGooseType不会调用resolve。
You can verify this by running it on a single goose rather than 10 geese.
您可以通过在一只鹅而不是10只鹅上运行来验证这一点。
#1
1
You don't have an array of promises, you have an array of undefined
values (and Q.all
didn't warn you about it): Your mapper function is not returning anything. You're missing a return
statement there:
你没有一个promises数组,你有一个未定义值的数组(并且Q.all没有警告你):你的mapper函数没有返回任何东西。你错过了那里的退货声明:
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);
#2
1
This means there are two options:
这意味着有两种选择:
Either recordNewGooseType
is promisified incorrectly or determineGooseType
is. Specifically - since you said the API response determineGooseType
returns [null, null]
the only reasonable assumption is that recordNewGooseType
is to blame.
recordNewGooseType被错误地宣告或者确定GooseType是。具体来说 - 既然你说API响应confirmGooseType返回[null,null],那么唯一合理的假设就是责备recordNewGooseType。
This means that the promisified recordNewGooseType
is not calling resolve
.
这意味着promisified recordNewGooseType不会调用resolve。
You can verify this by running it on a single goose rather than 10 geese.
您可以通过在一只鹅而不是10只鹅上运行来验证这一点。