使用q.map时如何避免破坏保证链?

时间:2022-05-09 08:35:36

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只鹅上运行来验证这一点。