简体   繁体   English

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

[英]How to register a custom callback after Ember.RSVP.hash

I have a route that pulls in 2 different promises using RSVP like so 我有一条路线,使用RSVP就可以实现两种不同的承诺

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

The challenge is that I have a custom function I bind/invoke in the "then" of the 2nd promise shown above. 挑战在于我有一个自定义函数,我在上面显示的第二个promise的“then”中绑定/调用。 How can I invoke this when the callback happens along side another promise using RSVP? 当回调发生在另一个使用RSVP的承诺时,我如何调用它?

Here is the custom callback as it stands today (not inside of RSVP.hash just yet) 这是今天的自定义回调(不在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;

Okay, I'm not sure if I completely understand, but I'm going to take a stab at it, and if I'm wrong I'll just quickly edit as you say my guessing is wrong. 好吧,我不确定我是否完全理解,但是我要去捅它,如果我错了,我会快速编辑,因为你说我的猜测是错误的。

Promises are super awesome when you do chaining of them ( .then ). 当你把它们链接起来时,承诺是非常棒的( .then )。 Let me see if I can do some quick examples and see if this applies to what you're doing. 让我看看我是否可以做一些简单的例子,看看这是否适用于你正在做的事情。

Chaining returns the last result. 链接返回最后的结果。

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 http://emberjs.jsbin.com/levoyama/1/edit

Chaining returns the deepest result. 链接返回最深的结果。 If you return a promise as the result of the then, it waits on that to resolve, and returns the result of it. 如果你返回一个promise作为then的结果,它会等待解析,并返回它的结果。 Quick note: cast is a quick way to cast anything into a promise , making it thenable. 快速注释:强制转换是一种快速的方式,可以将任何内容转化为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 http://emberjs.jsbin.com/voxevucu/1/edit

Hash taking the latest and greatest 哈希采取最新和最伟大的

Hash is going to take the deepest/last result of any promise sent to it, and use the result of that in its resultant hash. Hash将获取发送给它的任何promise的最深/最后结果,并在其结果哈希中使用该结果。 In the example below, both promise 1 and promise 2 will result in 5, despite their initial promise values being 1/2. 在下面的示例中,承诺1和承诺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 http://emberjs.jsbin.com/vevaruta/1/edit

Sharing promises/multiple observers 分享承诺/多个观察员

I reread the question and have another guess. 我重新阅读了这个问题并再次猜测。 Promises can have infinite number of observes that will all fire when the promise is resolved, if you need to use a promise for two different purposes. 如果您需要为两个不同的目的使用承诺,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 http://emberjs.jsbin.com/sovolibo/1/edit

In the scenario where you want the result (for the model) to be modified after both promises were resolved you would do something like this. 在您希望在两个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;
  });
}

The result of the model ends up being 3, not a hash, cause we did some post processing with the resultant of the hash. 模型的结果最终为3,而不是哈希,因为我们使用哈希的结果进行了一些后处​​理。

But if you want to do something async, as in it doesn't matter for the model's sake, it would be something like this: 但是如果你想做一些异步,就像模型一样无关紧要,它会是这样的:

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;
}

In this scenario, the model hook needs the hash, but then you want to do something different with the results when it's finished, and the model hook doesn't need to wait on the random promise after the fact. 在这种情况下,模型钩子需要哈希,但是当你完成时你想要对结果做一些不同的事情,并且模型钩子不需要在事实之后等待随机的诺言。

The answer above is extrememly helpful. 上面的答案极其有用。 I simply want to chime in with an alternate example for resolving: 我只是想用一个替代的例子来解决:

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;

This would immediately render the values 'red', 'yellow' and 'blue' and over the next three seconds render 'orange', then 'green', and finally 'pink'. 这将立即呈现值“红色”,“黄色”和“蓝色”,并在接下来的三秒内呈现“橙色”,然后呈现“绿色”,最后呈现“粉红色”。 Hopefully this isn't too redundant. 希望这不是多余的。

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

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