承诺成功回调链接承诺后不会被调用

时间:2014-04-17 16:59:09

标签: javascript ember.js promise rsvp-promise

根据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)

2 个答案:

答案 0 :(得分:3)

您正在向延迟的jquery返回RSVP承诺。并且jquery deferreds没有履行被拒绝承诺的功能。因此,您需要更新样本以使用Em.RSVP.Promise.cast(deferred),以转换RSVP承诺中的延迟,该承诺实现promises/a+ spec并执行您想要的操作:

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

答案 1 :(得分: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);
        });
    }
});