在Ember中进行异步调用的正确方法是什么?

时间:2015-06-12 00:19:54

标签: ember.js promise ember-cli

对于特定的服务调用,我使用的是jQuery而不是ember数据:

return Ember.$.get(url).then((json) => {
  this.store.pushPayload('user', json);
  return this.store.getById('user', json.user.id);
});

这打破了余烬的测试:

  

未捕获错误:断言失败:您已打开测试模式,该模式禁用了运行循环的自动运行。                     您需要在运行

中包装具有异步副作用的任何代码

我可以通过在promise的.then函数中添加一个run来解决这个问题:

return Ember.$.get(url).then((json) => {
  Ember.run(() => {
    this.store.pushPayload('user', json);
    return this.store.getById('user', json.user.id);
  })
});

这对我来说不起作用,因为Ember.run(..)没有返回任何内容,所以我的承诺解析为undefined。我已经看到一些建议将Ember.run移出一个级别,所以它包装了返回promise的方法。然后,这将返回正确的值,但测试将继续失败。

在不破坏测试的情况下,返回一个解析为值的promise的正确方法是什么?

谢谢!

修改1

我确实让它使用了这段代码:

var self = this;
return Ember.$.get(url).then((json) => {
    return new Ember.RSVP.Promise(function(resolve, reject) {
      Ember.run(function() {
        self.store.pushPayload('user', json);
        var user = self.store.getById('user', json.user.id);
        debugger;
        resolve(user);
      });
    });
});

这是正确的方法吗?为了进行ajax调用,感觉好像增加了很多复杂性。

3 个答案:

答案 0 :(得分:0)

Ember.RSVP.Promise然后resolve中包裹您的异步通话。示例(摘自route' model挂钩:

var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
    Ember.$.get(url).then((json) => {
        var record = self.store.pushPayload('user', json);
        Ember.run(null, resolve, record);
        return record;
    });
});

答案 1 :(得分:0)

编辑:

在Ember 1.13+中,使用Ember Ajax的首选方式是使用Ember Ajax - https://github.com/ember-cli/ember-ajax

由于您只是使用jQuery的$.ajax方法,因此您应该使用“ic-ajax”库,它实际上包含在使用ember-cli创建的所有新Ember项目中。 < / p>

这个库基本上可以在Ember.run中完成JQuery Ajax调用的所有包装,因此您可以轻松地进行测试。

例如,使用您的示例:

import Ember from 'ember'
....
....
return Ember.$.get(url).then((json) => {
  this.store.pushPayload('user', json);
 return this.store.getById('user', json.user.id);
});

会变成

import Ember from 'ember'
import request from 'ic-ajax'
....
....
return request(url).then((json) => {
    ....
});

比在Ember.run自己包装所有ajax调用更清洁

答案 2 :(得分:0)

现在有一个更新/更高级的东西可供使用:Ember Fetch