2013-09-30 21 views
6

Tôi đang viết ứng dụng Javascript API bằng jQuery. Phương thức yêu cầu cấp cao nhất của tôi trông giống như sau:Cung cấp phương thức 'không thành công' mặc định cho đối tượng bị trì hoãn jQuery

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

Làm cách nào để có trình xử lý hoãn trả về mặc định là fail? Nghĩa là, nếu hoãn lại không có trình xử lý nào khác được gắn với điều kiện fail của nó, hãy gọi trình xử lý mặc định.

Tôi muốn thực hiện việc này để xử lý ngoại lệ toàn cục trong ứng dụng của mình, ngoại trừ các phần có xử lý cụ thể (và sẽ xác định trình xử lý fail riêng của họ trên trì hoãn).

+5

đối tượng trì hoãn không làm việc theo cách đó. Thay vào đó, có một trình xử lý lỗi toàn cầu và sau đó vô hiệu hoá các sự kiện toàn cục cho yêu cầu ajax đó. –

+0

Không sử dụng giao diện '$ .Deferred' tại đây. Chỉ cần gọi phương thức 'then' (hoặc' pipe' trong các phiên bản jQuery cũ) trên lời hứa được trả về bởi '$ .ajax()'! – Bergi

+0

Có sự kiện ['ajaxError' toàn cầu] (http://api.jquery.com/ajaxError/) và bạn có thể sử dụng [' $ .ajaxSetup'] (http://api.jquery.com/jQuery.ajaxSetup /) cho các tùy chọn mặc định. – Bergi

Trả lời

3

Vì vậy, cách tốt nhất để sử dụng jQuery ajax trong API vào năm 2016 là trả lại lời hứa. Tuy nhiên, bạn không thể xác định liệu người gọi có đính kèm một trình xử lý lỗi hay không với lời hứa. Vì vậy, những gì tôi muốn đề nghị là bạn chỉ cần thêm một đối số mới vào hàm của bạn để cho hàm KHÔNG áp dụng xử lý lỗi mặc định vì người gọi sẽ xử lý việc xử lý lỗi. Và, tôi muốn đề nghị bạn tránh được những lời hứa chống mẫu bằng cách chỉ sử dụng lời hứa hiện $.ajax() đã trả thay vì tạo của riêng bạn trì hoãn:

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

Sau đó, người gọi chỉ quyết định xem có nên áp dụng xử lý lỗi của chính họ hoặc không:

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

hoặc, bạn có thể đi với một tổ chức phi hứa failHandler callback mà bạn vượt qua trong và xử lý lỗi mặc định của bạn trông để xem nếu đó failHandler được thông qua năm hay không. Đây là lai của lời hứa và callbacks và không phải là một cái gì đó tôi thường sẽ chọn để kiến ​​trúc sư, nhưng vì câu hỏi của bạn yêu cầu một điều gì đó hứa hẹn sẽ không hỗ trợ, đây là một trong đạt được rằng:

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; 
}; 
Các vấn đề liên quan