1

我无法按照 RSVP 文档获得连锁承诺。我有一个案例,我试图从服务器获取一些数据。如果由于某种原因发生错误,我想从本地文件中获取数据。

我正在尝试为此链接承诺。

我创建了一个简化的示例。下面的示例将给出一个输出,但不是我想要的。 http://emberjs.jsbin.com/cobax/3

App.IndexRoute = Em.Route.extend({
  model: function() {
    return Ember.$.getJSON('http://test.com/search')

    .then(undefined, function(errorObj, error, message) {
        return new Promise(function(resolve, reject) {
          resolve(model);
        }).then(function(response) {
          console.info(response.articles);
          return response.articles;
        });
    });
  }
});

这个例子是我想要的,但它不会调用最后的'then'。 http://emberjs.jsbin.com/cobax/3

App.IndexRoute = Em.Route.extend({
  model: function() {
    return Ember.$.getJSON('http://test.com/search')

    .then(undefined, function(errorObj, error, message) {
        return new Promise(function(resolve, reject) {
          resolve(model);
        });
    })

    .then(function(response) {
      console.info(response.articles);
      return response.articles;
    });
  }
});

基本上我想处理最后一个“then”方法的服务器/本地响应。我还希望将所有回调保持在一个级别。

第二个代码中的错误是什么?


更新

正如@marcio-junior 提到的,延迟的jquery 是问题所在。这是他的固定垃圾箱。 http://jsbin.com/fimacavu/1/edit

我的实际代码不返回模型对象,它向 json 文件发出另一个 getJSON 请求。我无法在 bin 中复制它,因为我认为 js bin 不允许我们托管静态文件。这是代码,但它不会工作。由于一些js错误,它失败了。

App.IndexRoute = Em.Route.extend({
  model: function() {
    var cast = Em.RSVP.Promise.cast.bind(Em.RSVP.Promise);
    return cast(Ember.$.getJSON('http://test.com/search'))

    .then(undefined, function(errorObj, error, message) {
        //return Em.RSVP.resolve(model);
        return cast(Ember.$.getJSON('data.json'));
    })

    .then(function(response) {
      console.info(response.articles);
      return response.articles;
    });
  }
});

你能帮我解决这个问题吗?这些承诺有点难以理解。

这是我看到的错误堆栈

XMLHttpRequest cannot load http://test.com/search. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. localhost/:1
Error while loading route: index ember-canary-1.7.0.js:3916
logToConsole ember-canary-1.7.0.js:3916
defaultActionHandlers.error ember-canary-1.7.0.js:39681
triggerEvent ember-canary-1.7.0.js:39763
trigger ember-canary-1.7.0.js:42317
Transition.trigger ember-canary-1.7.0.js:42162
(anonymous function) ember-canary-1.7.0.js:42017
invokeCallback ember-canary-1.7.0.js:10498
publish ember-canary-1.7.0.js:10168
publishRejection ember-canary-1.7.0.js:10596
(anonymous function) ember-canary-1.7.0.js:15975
DeferredActionQueues.flush ember-canary-1.7.0.js:8610
Backburner.end ember-canary-1.7.0.js:8082
(anonymous function)
4

2 回答 2

3

您正在向延迟的 jquery 返回一个 RSVP 承诺。并且 jquery deferreds 不具有履行被拒绝承诺的功能。因此,您需要更新您的示例以使用Em.RSVP.Promise.cast(deferred)来转换 RSVP 承诺中的 deferred,它实现了promises/a+ 规范并执行您想要的操作:

App.IndexRoute = Em.Route.extend({
  model: function() {
    return Em.RSVP.Promise.cast(Ember.$.getJSON('http://test.com/search'))
      .then(undefined, function() {            
        return getDefaultData();
      })
      .then(function(response) {
        console.info(response.articles);
        return response.articles;
      });
  }
});

您更新的jsbin

于 2014-04-17T18:16:02.893 回答
0

这是我使用的最终路线代码。它只是检查我的应用程序 api 的结果。如果它不存在,我会从示例 json 文件中获取静态结果。响应的解析发生在最后,无论它来自哪里。

var App.IndexRoute = Ember.Route.extend({
    model: function() {
        var cast = Em.RSVP.Promise.cast.bind(Em.RSVP.Promise);
        return  cast(Ember.$.getJSON('http://test.com/search'))

        .then(undefined, function(error) {
            console.info(error);
            return Ember.$.getJSON('assets/data.json');
        })

        .then(function(response) {
            console.info(response);
            return JSON.parse(response);
        });
    }
});
于 2014-04-18T13:12:39.903 回答