将 ajax 调用封装在延迟对象中并允许中止

Encapsulating a ajax call in a deferred object and allow an abort

我正在尝试创建一个全局 ajax 调用来处理一些全局功能,例如:

json

{
  Data : { /* some object returned */ },
  RedirectTo: "",   // for example: "/Account/Login"
  ErrorMessage: "", // for example: "You have been logged out do to inactivity.
}

jquery

(function (global, $, undefined)
{
  global = global || {};

  global.ajax = function(settings)
  {
    var timeoutResult = {
      Data: null,
      RedirectTo: null,
      ErrorMessage: "Your request could not be completed, please try again.";
    }

    var customResult;
    var jqXHR;
    var $deferred = $.Deferred(function()
    {
      var ajaxSettings = $.extend({
          statusCode: {
            408: function()
            {
              customResult = timeoutResult; 
            },
          },
        }, settings);


      var self = this;
      jqXHR = $.ajax(ajaxSettings )
        .always(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (jsonResult.RedirectTo
              && jsonResult.RedirecTo !== null)
          {
            window.location = jsonResult.RedirectTo;
          }
        })
        .fail(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (/* some logic to bubble up fail() */)
          {
            self.reject(jsonResult);
          }
        })
        .done(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (/* some logic to bubble up done() */)
          {
            self.resolve(jsonResult);
          }
        });
    };

    return ???;

  };
}(window.global, jQuery));    

现在的问题是我希望用户能够 .abort().done().fail(),但我不希望他们将延迟调用直接附加到 jqXHR 但如果我不这样做,他们就不能打电话给 abort().

我可以 return 一个像这样的对象:

{
  jqXHR: jqXHR,
  deferred: self
}

但是这样就不直观了。

Reason?

我需要控制哪些 done()fail() events/methods 冒泡到开发人员代码。如果用户注销,我将立即重定向他们。其他开发者代码不需要执行也不应该真的执行。

How will request be aborted ?

开发人员希望能够:

jqXHR.abort();

不管什么原因。

我早该知道在 Javascript 世界中我可以根据需要扩展对象:

global.ajax = function(settings)
  {
    var timeoutResult = {
      Data: null,
      RedirectTo: null,
      ErrorMessage: "Your request could not be completed, please try again.";
    }

    var customResult;
    var jqXHR;
    var $deferred = $.Deferred(function()
    {
      var self = this;

      var ajaxSettings = $.extend({
          statusCode: {
            408: function()
            {
              customResult = timeoutResult; 
            },
          },
        }, settings);


      jqXHR = $.ajax(ajaxSettings )
        .always(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (jsonResult.RedirectTo
              && jsonResult.RedirecTo !== null)
          {
            window.location = jsonResult.RedirectTo;
          }
        })
        .fail(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (/* some logic to bubble up fail() */)
          {
            self.reject(jsonResult);
          }
        })
        .done(function(jsonResult)
        {
          if (customResult) jsonResult = customResult;
          if (/* some logic to bubble up done() */)
          {
            self.resolve(jsonResult);
          }
        });

      // add the abort method... 
      self.abort = jqXHR.abort;

    };
  };

return $deferred;