如何在Ember.RSVP.hash之后注册自定义回调

时间:2014-05-15 14:37:06

标签: ember.js rsvp.js

我有一条路线可以使用RSVP来实现两种不同的承诺

model: function() {
  return Ember.RSVP.hash(function() {
    stuff: App.Thing.find(),
    other: this.store.find('appointments', {day: day})    
  });
}

挑战在于我有一个自定义函数,我在上面显示的第二个promise的“then”中绑定/调用。当回调发生在另一个使用RSVP的承诺时,我如何调用它?

这是今天的自定义回调(暂不在RSVP.hash内部)

    function bindContextAndGenerateAvailable(employee, other, appointments) {
        return function(filteredAppointments) {
            //will take the filtered collection and do something w/ it
            //to populate the bound appointments array passed in
        }
    }

    var appointments = Ember.A([]);
    this.store.find('appointment', {day: day}).then(function(response) {
        Ember.RSVP.all(response.getEach('employee')).then(function(empls){
          var filtered = response.filterBy('employee.id', employee);
          Ember.RSVP.resolve(filtered).then(bindContextAndGenerateAvailable(employee, other, appointments));
        });
    });
    return appointments;

2 个答案:

答案 0 :(得分:8)

好吧,我不确定我是否完全理解,但是我要去试一试,如果我错了,我会快速编辑,因为你说我的猜测是错误的。

当你对它们进行链接时,Promise是非常棒的(.then)。让我看看我是否可以做一些简单的例子,看看这是否适用于你正在做的事情。

链接返回最后一个结果。

var foo = new Ember.RSVP.Promise(function(resolve){
  resolve(1);
}).then(function(result){
  return result + 2;
});

foo.then(function(result){
  alert(result); // this will alert 3, not 1
});

http://emberjs.jsbin.com/levoyama/1/edit

链接返回最深的结果。如果你返回一个promise作为then的结果,它会等待解析,并返回它的结果。快速注释:强制转换是将任何内容强制转换为promise的快速方法,使其成为可能。

var bar = Ember.RSVP.Promise.cast(1).then(function(result){
  return new Ember.RSVP.Promise(function(resolve){
    resolve(2 + result);
  });
});

bar.then(function(result){
  alert(result); // this will alert 3, not 1
});

http://emberjs.jsbin.com/voxevucu/1/edit

哈希采取最新最好的

Hash将获取发送给它的任何promise的最深/最后结果,并在其结果哈希中使用该结果。在下面的例子中,promise 1和promise 2都会产生5,尽管它们的初始承诺值是1/2。

var promise1 = Em.RSVP.Promise.cast(1)
                 .then(function(result){ return result + 1; })
                 .then(function(result){ return result + 1; })
                 .then(function(result){ return result + 1; })
                 .then(function(result){ return result + 1; });

var promise2 = Em.RSVP.Promise.cast(2)
                 .then(function(result){
                  return new Ember.RSVP.Promise(function(resolve){
                    resolve(result + 3);
                  });
                 });


var hash = Em.RSVP.hash({
   p1: promise1,
   p2: promise2
});

hash.then(function(result){
  alert(result.p1 + ' + ' + result.p2 + ' = ' + (result.p1 + result.p2) + ', alert the presses!!!!');
});

http://emberjs.jsbin.com/vevaruta/1/edit

分享承诺/多个观察员

我重读了这个问题并再次猜测。如果您需要将承诺用于两个不同的目的,Promise可以拥有无​​限数量的观察结果,这些观察结果将在解决承诺时触发。

var promise1 = Em.RSVP.Promise.cast('of warcraft');

promise1.then(function(result){
  alert('hello world ' + result);
});

promise1.then(function(result){
  alert('stop playing world ' + result);
});

Em.RSVP.hash({
  p: promise1
}).then(function(hash){
  alert('hash result p is: ' + hash.p);
});

http://emberjs.jsbin.com/sovolibo/1/edit

在你希望在两个promise都得到解决后修改结果(对于模型)的情况下,你会做这样的事情。

model: function(){
  var promise1 = Ember.RSVP.Promise.cast(1);
  var promise2 = Ember.RSVP.Promise.cast(2);

  return Ember.RSVP.hash({
    p1 = promise1,
    p2 = promise2
  }).then(function(result){
      return result.p1 + result.p2;
  });
}

模型的结果最终为3,而不是散列,因为我们使用散列的结果进行了一些后处​​理。

但是如果你想做一些异步,就像模型一样无关紧要,就像这样:

model: function(){
  var promise1 = Ember.RSVP.Promise.cast(1);
  var promise2 = Ember.RSVP.Promise.cast(2);

  var hash = Ember.RSVP.hash({
    p1 = promise1,
    p2 = promise2
  });

  var randomPromise = hash.then(function(result){
    return result.p1 + result.p2;
  });

  randomPromise.then(function(result){
    alert(result);
  });

  return hash;
}

在这种情况下,模型钩子需要哈希,但是当你完成时你想要对结果做一些不同的事情,并且模型钩子在事后不需要等待随机的诺言。

答案 1 :(得分:1)

上面的答案是极端有用。我只是想用一个替代的例子来解决:

var promise, colors = ['red', 'yellow', 'blue'];

promise = new Ember.RSVP.Promise(function(resolve, reject) {

  // timeouts below mimic a webservice response with new data
  setTimeout(function() {
    colors.pushObject('orange');
  }, 1000);

  setTimeout(function() {
    colors.pushObject('green');
  }, 2000);

  Ember.run.later(colors, function() {
    colors.pushObject('pink');
  }, 3000);

  resolve(colors);
});

return promise;

这将立即呈现值“红色”,“黄色”和“蓝色”,并在接下来的三秒内呈现“橙色”,然后呈现“绿色”,最后呈现“粉红色”。希望这不是多余的。