Search code examples
jqueryajaxember.jsember-app-kit

Wrapping jquery $.ajax in RSVP.Promise blows up the whole application


UPDATE 1: Added another surprisingly non-working code sample

UPDATE 2: I went back to start and did a rewrite of my newly implemented logic - it works now


I'm using Ember.js along with the (now deprecated) ember-app-kit layout and conventions. The main libraries versions are:

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

As I had the intention to keep all my Ajax requests in one place I came up with an AjaxManager class which handeled all my requests with the following code:

function async (requestObj, successCallback, errorCallback) {

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

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

Now, as I got further and my code evolved I wanted to wrap this in a Ember.RSVP.Promise object, just to have some convenience when calling it from my model hooks and the like. So I did the following:

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

But, what happens now is that my first Ember.RSVP.Promise gets resolved as expected, but all further Promises remain unresolved/unrejected which means it hangs the whole application and drives Chrome to blow up the page thread and gather more and more RAM (which is summing up frequently and is only stoppable by killing the process).

So, basically Ember.RSVP.Promise blows up $.ajax! I also tried it with Ember.RSVP.defer(), or using the jqXHR.beforeSend method get the promise/deferred resolved/rejected but it's always the same: the first promise gets resolved/rejected, all others are hanging and will never come up again...


UPDATE 1:

I tried it with plain XMLHttpRequest, leaving jQuery.ajax behind, and an RSVP.defer() deferred object, but it's giving me the same result:

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

UPDATE 2:

As I ran out of ideas and not a single char of error code or something else came out of the dev tools console I finally reverted my huge pile of code and made a hard reset. I implemented the code in smaller steps/commits/chunks and now it works! I have absolutely no idea what was causing this issue as the code is pretty much the same...


Has anybody run into a similar issue or can give me some advice or hint in the right direction?


Solution

  • In the end, only a revert & rewrite did the trick - sorry for all you future devs running into something similar, but there's no real solution to my problem other than doing it again. This drove me nuts!

    I'll accept this answer as the solution to my problem so that this could be closed.