当前位置: 首页 > 知识库问答 >
问题:

等待嵌套的promise完成

庄弘业
2023-03-14

我有一个复杂的对象图,我建立在一个Ember控制器。

export default Container({
  username: DS.attr('string'),
  items: DS.hasMany('item')
})

export default SomeDetail({
  foo: DS.attr('string')
})

export default Item({
  detail_type: DS.attr('string'),
  detail_id: DS.attr('number'),
  container: DS.belongsTo('container')
})

所以,为了安排这一切,我基本上是想

  1. 创建conatainer,
  2. 然后,创建细节,其中可能有许多
  3. 然后,创建项目,其中会有尽可能多的细节
  4. 等待一切promise解决
  5. 启动一个自定义的Rest动作来“激活”html" target="_blank">容器,一旦它有了所有的东西。

代码看起来像这样(咖啡),简化了但我认为要点就在那里

promises = []
store = @store
items = @get('itemsInMyController')
store.createRecord('container',
  username: @get('username')
).save().then(container) ->
  items.forEach (item) ->
    store.createRecord('detail',
      # Set Properties
    ).save().then (detail) ->
      item = store.createRecord('item',
        # Set Properties
      )
      promsies.push item
      item.save()

Ember.RSVP.allSettled(promsies).then (responses) ->
  # Perform Activate Action

当所有的promise都解决了,一切都是我想要的,然而,allSettled启动得太早了,因为它是在细节解决之前到达的,所以项目还没有创建,所以数组中没有任何内容。如果我将细节添加到数组中,也会发生这种情况,因为在创建项之前就已经到达了数组。

我唯一能做的就是使用单独的数组来跟踪不同的promise,并在每个promise解决时使用嵌套的all解决方案,但这开始让人感到非常棘手,我想知道是否有更好的方法。

谢谢

共有1个答案

方昊阳
2023-03-14

您需要从返回promise,然后返回回调,这样您就可以正确地取消它们的嵌套。因此,首先从回调返回项目promise,并获得一个promise,您可以立即在循环中推送到您的promise数组:

promises = []
@get('itemsInMyController').forEach (item) =>
  promise = @get('store').createRecord('detail',
    # Set Properties
  ).save().then (detail) =>
    item = @get('store').createRecord('item',
      # Set Properties
    )
    item.save() # this returns a promise
  ) # and `promise` resolves with that result eventually
  promises.push promise

现在,您得到了一系列promise,您可以将这些promise传递给allselled。您不能在容器的then回调之外调用它(因为promises到那时仍然是空的),而是在回调内部,您可以再次为数组返回该promise,以便展平链。

我建议不要为每个使用并手动构建该数组,只需使用映射

@store.createRecord('container',
  username: @get('username')
).save().then (container) =>
  promises = @get('itemsInMyController').map (item) =>
    @get('store').createRecord('detail',
      # Set Properties
    ).save().then (detail) =>
      @get('store').createRecord('item',
        # Set Properties
      ).save()
  Ember.RSVP.allSettled promises
.then (responses) ->
  # Perform Activate Action

 类似资料:
  • 我正在努力学习如何正确使用async Wait,但我对它有点共同的想法。 在片段中,我试图构建一个对象数组,其中包含我需要的关于我在组件中上传的文件的信息。问题是this.fileInfo中的对象并没有完全等待返回编码图像的promise,而是在我console.logthis.fileInfo时返回此输出: 如您所见,关键图像是一个值未定义的ZoneAwarePromise。你能帮我修一下吗?

  • 假设返回一个promise,该promise应解析为某个服务返回的随机新闻条目,而返回一个promise,该promise应解析为传递文本的翻译。 现在,页面最初显示了一个加载微调器,我希望在所有promise(包括嵌套的翻译promise)完成(成功或失败)后隐藏该微调器: 这段代码a)不能正常工作,因为加载微调器有时会在promise解决之前消失,b)非常复杂。 如何正确地做到这一点?(配香草

  • 我和Nodejs一起工作。我有一个异步,因为我必须等待内部的结果。因此,我需要等待foreach完成,然后继续循环的结果。我找到了几个等待的解决方案,其中一个是使用promise。虽然我这样做了,这些promise是创建的,但是,代码后的每个(因此promise)完成,从来没有实际执行(console.log没有打印)。NodeJS函数结束时没有任何错误。 这是我的密码: “here”只打印一次(

  • 问题内容: 我正在使用bluebird,方法 getAll 和 update return promises。我如何说“等到两个承诺返回,然后更新currentProduct值”?我对JS很陌生… 问题答案: 如果可以使用/,这将很简单。 或者,如果您只能使用简单的承诺,则可以遍历所有产品,并将每个承诺置于最后一个循环中。这样,仅当前一个问题解决时,它才会前进到下一个问题(即使它将首先迭代整个循环

  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 我不熟悉promise和使用NodeJS中的请求和promise编写网络代码。 我想删除这些嵌套的promise,并将它们链接起来,但我不确定该如何做/这是否是正确的方式。 这是请求代码: 如有任何见解,将不胜感激。