在 Durandal 传播 jquery/ajax 承诺

Propagation of jquery/ajax promises in Durandal

我正在使用 durandal.. 我有一个基本控制器来管理对服务器的调用...每个控制器,根据用例专门化,使用基本控制器来调用服务器。 在基本控制器中我有这个代码:

self.call = function (url, type, data, success) {
    return Q.when(
        $.ajax({
            ...
            error: function (jqXHR, textStatus, errorThrown) {
                if (jqXHR.status == 500) {
                   // Do some work
                }
            }
        })
     );

然后,在我的专用控制器中,我有

myController.execute(command)
      .then(function () {
            //Do work ok
       })
        .fail(function (data) {
             //Manage error
       });

execute方法,内部调用我一开始写的call方法... 这个解决方案的问题是,当我在基本控制器中管理错误时,我也在专用控制器中执行 fail 代码...

我试过的另一种方法...在基本控制器中

self.call = function (url, type, data, success) {
    return Q.fail(function (jqXHR, textStatus, errorThrown) {
        if (jqXHR.status == 500) {
             app.showError("a new error");
        }
         else 
             throw { "jqXHR": jqXHR, "textStatus": textStatus, "errorThrown": errorThrown };
    });

在这种情况下,then 代码在专用控制器中执行。在这种情况下,如何避免停止传播承诺?

谢谢

而不是这样做:

myController.execute(command)
      .then(function () {
            //Do work ok
       })
        .fail(function (data) {
             //Manage error
       });

你应该这样做:

myController.execute(command)
      .then(function (data) {
            //Do work ok
       }, function (reason) {
            //error handled 
            //you need to manully throw error here if you want the error to be propagated
            //throw reason; 
       });

更新 你不必用 q 包装 jquery promise,这是另一种方法:

self.call = function (url, type, data, success) {
  var result = Q.defer();

  $.ajax({
     success: function (data) {
        result.resolve(data);
     },
     error: function (jqXHR, textStatus, errorThrown) {
       if (jqXHR.status == 500) {
          console.log('error 500, handled');
       } else {
          result.reject(textStatus);
       }
    }
  });

  return result;
}

这样您可能 "propagate" 有条件地出错,但我不推荐这样做,因为未决承诺(既未解决也未拒绝)可能是内存泄漏的潜在来源。