简体   繁体   English

等待嵌套的承诺完成

[英]Waiting for Nested Promises to complete

I have a complicated object graph I'm building up in an Ember Controller. 我有一个复杂的对象图,我在灰烬控制器建立。

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')
})

So, to set all this up, I'm basically trying to 因此,为了进行所有设置,我基本上是在尝试

  1. Create the conatainer, 创建容器,
  2. Then, create the details, of which there may be many 然后,创建细节,其中可能有很多
  3. Then, create the items, of which there will be as many of the details 然后,创建项目,其中会有尽可能多的细节
  4. Wait for all promises to resolve 等待所有诺言解决
  5. Fire off a custom rest action to "activate" the container once it has all of it's stuff. 一旦容器装满了所有东西,请执行自定义的休息操作以“激活”容器。

The code looks like this (coffee), simplified but I think the gist is there 代码看起来像这样(咖啡),简化了,但我认为要旨在那里

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

When all the promises resolve, everything is how I want it, however, allSettled is firing way too soon, because it's reached before the details have resolved, so the items haven't been created, so there's nothing in the array. 当所有的诺言都解决了,一切都是我想要的,但是,allSettled开火太早了,因为在细节解决之前就已经达成了,所以还没有创建项目,因此数组中什么也没有。 This also happens if I add the details to the array, because it's still reached well before the items have been created. 如果我添加细节到数组,因为已经创建项目之前它仍然达到了很好也会发生这种情况。

The only thing I can thing of is to have separate arrays tracking the different promises, and having a nested allSettled as each one resolves, but this is starting to feel pretty hairy, and I'm wondering if there's a better way. 我唯一能做的就是让单独的数组跟踪不同的promise,并在每个解析时嵌套一个allSettled,但是这开始变得非常麻烦,我想知道是否有更好的方法。

Thanks! 谢谢!

You need to return promises from your then callbacks so that you can properly unnest them. 您需要从then回调中return promise,以便可以正确地将它们嵌套 So first return the item promise from that callback and get a promise that you can actually push to your promises array immediately in that loop: 因此,首先从该回调return项目Promise,并获得一个Promise,您实际上可以立即在该循环中将其推送到promises数组:

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

Now you got an array of promises that you can actually pass to allSettled . 现在,您有了一个可以实际传递给allSettled的诺言数组。 You must not call that outside of the then callback for the container as well (because promises would still be empty by then), but inside the callback, and you can again return that promise for the array so that you flatten your chain. 您也不能在容器的then回调之外也调用它(因为promises届时仍然为空),而在回调内部,则可以再次为数组返回那个promise以便平整链。

And I'd recommend not to use forEeach and manually build up that array, just use map : 而且我建议不要使用forEeach并手动构建该数组,只需使用map

@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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM