1

更新 1: 添加了另一个令人惊讶的非工作代码示例

更新 2: 我重新开始并重写了我新实现的逻辑 - 它现在可以工作了


我正在使用Ember.js(现已弃用)ember-app-kit布局和约定。主要的库版本是:

DEBUG: -------------------------------
DEBUG: Ember      : 1.4.0
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery     : 2.1.0
DEBUG: -------------------------------

由于我打算将所有Ajax请求保存在一个地方,我想出了一个AjaxManager类,它使用以下代码处理我的所有请求:

function async (requestObj, successCallback, errorCallback) {

  requestObj.async = true; // just to be sure it's really asynchronous

  return $.when($.ajax(requestObj)).then(successCallback, errorCallback);
}

现在,随着我的进一步发展和代码的发展,我想将其包装在一个Ember.RSVP.Promise对象中,以便在从我的model钩子等调用它时获得一些便利。所以我做了以下事情:

function promisedAsync (requestObj) {

  requestObj.async = true; // just to be sure it's really asynchronous

  return new Ember.RSVP.Promise(function (resolve, reject) {
    requestObj.success = function (data) {
       resolve(data);
    };

    requestObj.error = function () {
      reject(arguments)
    };

    $.ajax(requestObj);
  });
}

但是,现在发生的事情是我的第一个Ember.RSVP.Promise问题按预期得到了解决,但是所有进一步的 Promise 仍然未解决/未拒绝,这意味着它会挂起整个应用程序并驱动 Chrome 炸毁页面线程并收集越来越多的 RAM(这是经常总结并且只能通过终止进程来停止)。

所以,基本上Ember.RSVP.Promise炸了$.ajax!我也尝试过Ember.RSVP.defer(),或者使用jqXHR.beforeSendget the promise/deferred resolved/rejected 方法,但它总是一样的:第一个 promise 被解决/拒绝,所有其他的都挂起并且永远不会再出现......


更新 1:

我尝试使用 plain XMLHttpRequest,留下jQuery.ajaxRSVP.defer()延迟对象,但它给了我相同的结果

var set = Ember.set,
    get = Ember.get,
    RSVP = Ember.RSVP;
//....
// some application code
//...

promisedAsync: function (ajaxData) {
    var url = get(ajaxData, 'url'),
        method = get(ajaxData, 'type').toUpperCase(),
        xhr = new XMLHttpRequest(), // developing on Chrome, no IE needed (until now) :)
        data = get(ajaxData, 'data'),
        deferred = RSVP.defer();

    if (method === 'GET') {
      url = this._prepareUrl(url, data); // takes the data and concatenates it so that the params are in the URL
    }

    xhr.open(method, url);

    xhr.setRequestHeader('Content-Type', 'application/json');

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        var response;

        try {
          response = JSON.parse(xhr.responseText);

          if (xhr.status === 200) {
            deferred.resolve(response);
          } else {
            deferred.reject(response);
          }

        } catch (e) {
          deferred.reject(e);
        }
      }
    };

    xhr.onabort = function () {
      deferred.reject('aborted');
    };

    if (method === 'GET') {
      xhr.send(null);
    } else {
      xhr.send(data);
    }

    return deferred.promise;
  }

更新 2:

当我的想法用尽时,没有一个字符的错误代码或其他东西从开发工具控制台中出来,我终于恢复了我的一大堆代码并进行了硬重置。我以较小的步骤/提交/块实现了代码,现在它可以工作了!我完全不知道是什么导致了这个问题,因为代码几乎相同......


有没有人遇到过类似的问题,或者可以给我一些正确方向的建议或提示?

4

2 回答 2

1

我也没有看到任何问题,为了测试起见,最好将它包装在一个Ember.run语句中,这是 Ember Data 如何做到这一点的副本(与您的几乎相同)。

 ajax: function(url, type, hash) {
    var adapter = this;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      hash = adapter.ajaxOptions(url, type, hash);  // this is your requestObj

      hash.success = function(json) {
        Ember.run(null, resolve, json);
      };

      hash.error = function(jqXHR, textStatus, errorThrown) {
        Ember.run(null, reject, adapter.ajaxError(jqXHR));
      };

      Ember.$.ajax(hash); // this is the same thing as $.ajax
    }, "DS: RestAdapter#ajax " + type + " to " + url); // they name their promise
  }
于 2014-08-06T14:21:38.787 回答
0

最后,只有恢复和重写才能解决问题 - 对所有遇到类似问题的未来开发人员感到抱歉,但除了重做之外,我的问题没有真正的解决方案。这让我发疯了!

我会接受这个答案作为我的问题的解决方案,以便可以关闭它。

于 2014-08-07T15:40:46.693 回答