等待嵌套Promise完成

时间:2015-06-01 20:04:07

标签: ember.js coffeescript promise

我有一个复杂的对象图,我在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. 等待所有承诺解决
  5. 启动自定义休息操作,以便在容器拥有所有内容后“激活”该容器。
  6. 代码看起来像这样(咖啡),简化但我认为要点是

    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
    

    当所有的承诺都解决了,一切都是我想要的,但是,allSettled太快了,因为它已经在细节解决之前到达了,所以没有创建项目,所以数组中什么都没有。如果我将详细信息添加到数组中也会发生这种情况,因为在创建项目之前它仍然很好。

    我能做的唯一事情就是让单独的数组跟踪不同的promises,并在每个promise解析时都有一个嵌套的allSettled,但这开始感觉非常毛茸茸,而且我想知道是否有更好的方法。

    谢谢!

1 个答案:

答案 0 :(得分:2)

您需要returnthen回复中的return承诺,以便您可以正确地unnest他们。因此,首先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 数组:

allSettled

现在你有一系列承诺,你可以实际传递给then。你也不能在容器的promises回调之外调用它(因为那时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

div
相关问题