2013-09-30 39 views
6

我写使用jQuery JavaScript API的客户端提供一个默认的“失败”的方法。我的顶级请求的方法是这样的:为一个jQuery Deferred对象

function request(method, uri, params, proxies) { 
    var deferred = $.Deferred(); 
    $.ajax({ 
    data: method == 'GET' ? params : JSON.stringify(params), 
    contentType: 'application/json', 
    dataType: 'json', 
    url: api.root + uri, 
    type: method, 
    xhrFields: { 
     withCredentials: true 
    } 
    }).done(function(body) { 
    deferred.resolveWith(this, [body.data]); 
    }).fail(function(xhr) { 
    deferred.rejectWith(this, [xhr]); 
    }); 

    return deferred.promise(); 
}, 

我怎样才能为我推迟返回的默认fail处理?也就是说,如果延期未装其他的处理程序,它是fail条件,调用默认的处理程序。

我想这样做是为了在我的应用程序中具有全局异常处理,除了具有特定处理的部分(并且将在延迟中定义它们自己的fail处理程序)。

+5

延迟对象不工作那样。相反,有一个全局错误处理程序,然后禁用该AJAX请求的全局事件。 –

+0

不要在这里使用'$ .Deferred'接口。只是呼吁通过'$就返回的诺言'then'方法(或在旧版本的jQuery'pipe')()'! – Bergi

+0

有一个全局['ajaxError'事件](http://api.jquery.com/ajaxError/),您可以使用['$ .ajaxSetup'](http://api.jquery.com/jQuery.ajaxSetup /)为默认选项。 – Bergi

回答

3

因此,使用jQuery AJAX的API作为2016年最彻底的方法是返回一个承诺。但是,您无法确定调用者是否已将错误处理程序附加到承诺中。

那么,我建议是,你只需要添加一个新的参数,以你的函数,告诉功能不应用默认的错误处理,因为主叫方将采取的错误处理服务。而且,我建议您只需使用现有的承诺$.ajax()已经返回,而不是创建自己的递延避免承诺反模式:

function request(method, uri, params, proxies, skipDefaultErrorHandling){ 
    // default error handling will be used if nothing is passed 
    // for skipDefaultErrorHandling 
    var p = $.ajax({ 
     data: method=='GET'?params:JSON.stringify(params), 
     contentType: 'application/json', 
     dataType: 'json', 
     url: api.root + uri, 
     type: method, 
     xhrFields: { 
      withCredentials: true 
     } 
    }); 
    if (!skipDefaultErrorHandling) { 
     // apply default error handling 
     p = p.then(null, function(jqXHR, textStatus, errorThrown) { 
      // put here whatever you want the default error handling to be 
      // then return the rejection with the various error parameters available 
      return $.Deferred().reject([jqXHR, textStatus, errorThrown]); 
     }); 
    } 

    return p; 
}; 

随后,呼叫者只需决定是否申请自己的错误处理或没有:

request(...).then(function(data) { 
    // success code here 
}); 

或者,你可以用一个非承诺去failHandler回调,你在通过和您的默认错误处理看起来,看看是否能在failHandler是通过与否。这是承诺和回调的混合,是不是我通常会选择建筑师,但由于你的问题问的东西,承诺不支持,这是一个实现这一目标:

function request(method, uri, params, proxies, failHandler){ 
    // default error handling will be used if nothing is passed 
    // for skipDefaultErrorHandling 
    var p = $.ajax({ 
     data: method=='GET'?params:JSON.stringify(params), 
     contentType: 'application/json', 
     dataType: 'json', 
     url: api.root + uri, 
     type: method, 
     xhrFields: { 
      withCredentials: true 
     } 
    }); 
    // apply default error handling 
    p = p.then(null, function(jqXHR, textStatus, errorThrown) { 
     if (failHandler) { 
      // call passed in error handling 
      failHandler.apply(this, arguments); 
     } else { 
      // do your default error handling here 
     } 
     // then keep the promise rejected so the caller doesn't think it 
     // succeeded when it actually failed 
     return $.Deferred().reject([jqXHR, textStatus, errorThrown]); 
    }); 

    return p; 
};