【问题标题】:Block until promise is resolved阻塞直到 promise 被解决
【发布时间】:2015-02-07 00:37:42
【问题描述】:

给定以下 Coffeescript 代码:

for groupID, groupObj of @cache.groups

  #do some other stuff

  #calling this function which is returning a promise
  @callcounter.findNumbers(groupID)
  .then (result) =>
    @cache.groups[groupID].someValue = result.someValue

在幕后,findNumbers 方法正在查询 SQL 数据库(使用繁琐,不支持并发查询)并返回一个 Promise(库:Q)

因此,代码执行不会进入for-loop 的下一次迭代,直到前一次的承诺得到解决。

你会如何以正确的方式做到这一点?

【问题讨论】:

  • 请问为什么这个问题被否决了?

标签: node.js coffeescript q


【解决方案1】:

您只需要按顺序调用findNumbers,对吗?你只需要链接你的承诺。

重要提示:由于您使用的是命令式循环而不是 [].forEach,因此您需要限定 groupIDgroupObject 变量的范围。

globalPromise = null

createScopedPromiseFn = (groupID, groupObject) =>
  return ->
    @callcounter.findNumbers(groupID).then (result) =>
       @cache.groups[groupID].someValue = result.someValue

for groupID, groupObj of @cache.groups
  createPromise = createScopedPromiseFn groupID, groupObj
  # The if here is for initialisation
  globalPromise = if globalPromise then globalPromise.then createPromise() else createPromise()

globalPromise.then ->
  # Here you have finished

在这段代码中,for 循环不受限制地迭代,但承诺实际上是按顺序解析的。

但是,我建议您改用 reduce 的函数式方法:

createScopedPromise = (groupIndex, group) =>
  @callcounter.findNumbers(groupIndex).then (result) =>
    @cache.groups[groupIndex].someValue = result.someValue

globalPromise = @cache.groups.reduce (promise, group, index) ->
  if promise
    return promise.then ->
      createScopedPromise index, group
  else # First promise
    return createScopedPromise index, group

globalPromise.then ->
  # Here you have finished

【讨论】:

  • 谢谢。函数式方法看起来很有希望。不过有一个缺点。看来我不应该在同一个reduce 中做#do some other stuff。实际上,我这样做是因为它很容易做到。但在我看来,在你的函数式方法中做同样的事情是错误的。
  • 再次使用 forEach/map 进行迭代。没关系。
猜你喜欢
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 2017-10-05
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
相关资源
最近更新 更多