2012-01-16 34 views
8

thực sự là câu hỏi đơn giản như chủ đề nói. Có cách nào để cung cấp cho xử lý ajax khác nhau một ưu tiên cao hơn/thấp hơn (có nghĩa là ở đây, rằng họ sẽ bắn trước đó)?jQuery - đặt ưu tiên xử lý Ajax

Tôi có ý gì? Vâng, tôi phải đối phó với một ứng dụng web khá lớn. Tấn yêu cầu Ajax được kích hoạt trong các mô-đun khác nhau. Bây giờ, mục tiêu của tôi là triển khai một cơ chế thời gian chờ phiên đơn giản. Mỗi yêu cầu gửi id phiên hiện tại làm tham số, nếu id phiên không hợp lệ nữa, tập lệnh phụ trợ của tôi trả về yêu cầu với bộ tiêu đề phản hồi tùy chỉnh (giá trị là một uri).

Vì vậy, tôi về cơ bản sẽ như thế này

window.jQuery && jQuery(document).ajaxComplete(function(event, xhr, settings) { 
    var redirectto = xhr.getResponseHeader('new_ajax_location'); 
    if(redirectto) { 
     location.href = redirectto; 
    } 
}); 

làm việc này như một say mê tất nhiên, nhưng vấn đề của tôi là sự kiện ajax toàn cầu này thực sự cần phải bị sa thải đầu tiên 100% thời gian, mà không phải vậy. Một số trình xử lý yêu cầu ajax gốc sẽ ném một lỗi vì dữ liệu bị thiếu hoặc không mong muốn, trong trường hợp đó, trình xử lý toàn cục không bao giờ được thực hiện.

Bây giờ, tôi sẽ rất vui nếu tôi không cần phải đi qua mọi trình xử lý yêu cầu duy nhất và làm cho nó không an toàn cho các phản hồi dữ liệu phiên không hợp lệ. Tôi muốn làm nhiều việc hơn ở một nơi cụ thể. Nhưng làm thế nào tôi có thể chắc chắn rằng người xử lý toàn cầu của tôi sẽ bị xử tử trước?

+0

Có thể bằng cách sử dụng gọi lại 'onSuccess'. – Stefan

+0

@Stefan: Tôi sẽ cần phải nắm bắt tất cả các kết quả có thể cho một yêu cầu, vì vậy 'complete' là khá tốt. Nhưng tôi cũng đã kiểm tra để đặt 'thành công' và' lỗi' theo cách thủ công, không may với cùng một hành vi. – jAndy

+0

Liên quan đến http://stackoverflow.com/questions/290254/how-to-order-events-bound-with-jquery, vì các sự kiện AJAX được triển khai bằng hệ thống sự kiện cốt lõi. –

Trả lời

1

Nếu tôi hiểu chính xác bạn, bạn muốn thêm yêu cầu gọi lại của riêng bạn vào các yêu cầu json ở khắp mọi nơi. Bạn có thể sử dụng móc ajaxPrefilter.

$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
     options.complete = function (jqXHR2, settings) { 
      var redirectto = jqXHR2.getResponseHeader('new_ajax_location'); 
      if(redirectto) { 
       location.href = redirectto; 
      } 
     } 
    }); 

Bạn cũng có thể thay đổi tùy chọn ở đó để thêm id phiên vào tham số yêu cầu.

0

jQuery cho phép bạn "vá" các phương thức của nó, chẳng hạn như .post/.ajax.

Bạn có thể vá (các) phương thức thích hợp để sự kiện AJAX đặc biệt của bạn luôn được kích hoạt trước khi mã bạn muốn gọi.

Đây là một số "mã giả-jQuery" sẽ giúp bạn bắt đầu. Tôi nghi ngờ nó hoạt động như vậy, nhưng nó thể hiện khái niệm cơ bản và nó sẽ giúp bạn bắt đầu.

(function($){ 
    var originalPost = $.post; 
    var calledSpecialOne = false; 
    $.post = function(url, data, success, dataType) { 
     if (!calledSpecialOne) { 
      originalPost(... your special AJAX query ...).then(function() { 
      originalPost(url, data, success, dataType); 
      } 
      calledSpecialOne = true; 
     } else { 
      originalPost(url, data, success, dataType); 
     } 
    } 
})(jQuery); 

Ở trên là dựa trên một số khác, không liên quan, mã tôi thử nghiệm, mà làm cho $ .each() làm việc cho không xác định/mảng null):

(function($){ 
    var originalEach = $.each; 
    $.each = function(collection, callback) { 
     return collection? originalEach(collection, callback) : []; 
    } 
})(jQuery); 

Lưu ý rằng nhiều tiếp xúc các hàm cũng được gọi nội bộ bởi jQuery, vì vậy hãy rất cẩn thận khi sử dụng thủ thuật này; bạn có thể phá vỡ một phần khác của jQuery hoặc gây ra rắc rối khác. Trong trường hợp các hàm AJAX, có lẽ bạn chỉ nên vá hàm bên trong nhất, để ngăn chặn đệ quy vô hạn. (FWIW, tôi đã không tìm thấy bất kỳ tác dụng phụ nào cho bản vá $ .each() cho đến nay).

+0

ngay cả khi tôi thích nguyên tắc đấm vịt, tôi không thích nó trong tình huống cụ thể này. Tôi sẽ phải vá tất cả các thói quen ajax có sẵn, hoặc chỉ vá '.ajax()', nhưng điều này một lần nữa tôi không thực sự dám thực sự. Nhưng tôi có thể không có sự lựa chọn nếu không có khả năng chính thức để sửa đổi lệnh gọi một cách an toàn. – jAndy

0

Tôi không chắc chắn nếu điều này thậm chí là những gì bạn có nghĩa là, nhưng tôi figured tôi có thể cần nó như là một số điểm anyway.

Nó vá chức năng ajax của jQuery để chấp nhận đối tượng có thuộc tính priority. Nếu không có mức độ ưu tiên được đặt, mức độ ưu tiên của nó sẽ là 1 (ưu tiên cao nhất 0). Nếu có một ưu tiên, nó thực hiện một trong hai điều. Nếu mức độ ưu tiên là 5, nó sẽ kiểm tra xem cuộc gọi ajax có ưu tiên trước đó (trong trường hợp này là 4) đã được gọi hay chưa. Nếu không, nó sẽ thêm nó vào một mảng các cuộc gọi ajax với mức ưu tiên đó (trong trường hợp này là 5).Nếu ưu tiên trước đó đã được gọi, nó sẽ gọi yêu cầu bình thường. Khi một yêu cầu được gọi với mức ưu tiên, nó sẽ gọi bất kỳ yêu cầu gửi đi nào có mức độ ưu tiên cao nhất tiếp theo.

Nói cách khác, nếu không có ưu tiên, nó chờ ưu tiên 0, nếu có mức độ ưu tiên, nó sẽ đợi mức độ ưu tiên bên dưới nó để gọi. Nếu bạn muốn cuộc gọi không có ưu tiên được gửi đi ngay lập tức, bình luận ra phù hợp với nhận xét Tôi đặt nói default action?

(function($){ 
     var oldAjax=$.ajax; 
     var outgoing=[]; 
     var sent=[]; 
     $.ajax=function(url, settings) { 
      var pr = (typeof url==='object'?url:settings).priority; 
      pr = pr===undefined ? 1 : pr; // default action? 
      if(pr!==undefined){ 
       if(pr==0 || sent[pr-1]!==undefined){ 
        oldAjax(url,settings); 
        sent[pr]=true; 
        if(outgoing[pr]){ 
         var rq=outgoing[pr].splice(0,1)[0]; 
         $.ajax(rq[0],rq[1]); 
        } 
        if(outgoing[pr+1]){ 
         var rq=outgoing[pr+1].splice(0,1)[0]; 
         $.ajax(rq[0],rq[1]); 
        } 
       } 
       else{ 
        if(outgoing[pr]!==undefined){ 
         outgoing[pr].push([url,settings]); 
        } 
        else{ 
         outgoing[pr]=[[url,settings]]; 
        } 
       } 
      } 
      else{ 
       oldAjax(url, settings); 
      } 
     }; 
    })(jQuery); 

Patches cho getpost. Bạn sẽ phải bao gồm các đối số thừa đó hoặc tự thay đổi điều này để ưu tiên làm việc với các yêu cầu postget. Điều này là trực tiếp từ jQuery 1.7, ngoại trừ các đối số thêm, và hai dòng tôi thêm ý kiến.

jQuery.each([ "get", "post" ], function(i, method) { 
    jQuery[ method ] = function(url, data, callback, type, priority) { 
     // shift arguments if data argument was omitted 
     if (jQuery.isFunction(data)) { 
      priority = type; // my change 
      type = type || callback; 
      callback = data; 
      data = undefined; 
     } 

     return jQuery.ajax({ 
      type: method, 
      url: url, 
      data: data, 
      success: callback, 
      dataType: type, 
      priority: priority // my change 
     }); 
    }; 
}); 

tôi thiết lập một ví dụ ở đây: http://jsfiddle.net/tk39z/

Tôi thực sự tạo ra một số yêu cầu ajax nhắm mục tiêu google, vì vậy bạn có thể kiểm tra bảng điều khiển mạng trong Chrome để xem các yêu cầu.

0

Gần đây, tôi đã triển khai một cái gì đó rất giống với chức năng mà tôi tin rằng bạn đang tìm kiếm.

Tôi thiết lập bộ lọc ở phía máy chủ để kiểm tra phiên hợp lệ và nếu không, hãy trả lại lỗi 401 với văn bản trạng thái tùy chỉnh để biết chi tiết lỗi cụ thể hơn.

Cuộc gọi ajax mà tôi đã thực hiện cho các trang này được viết trong quy ước thông thường bằng thuộc tính 'thành công'.

Đối với các trường hợp có lỗi, tôi đã thêm gọi lại toàn cục vào hàm lỗi sẽ kiểm tra lỗi cụ thể và chuyển hướng tương ứng. chẳng hạn như:

$(document).ajaxError(function(e, xhr) { 
    var redirectto = xhr.getResponseHeader('new_ajax_location'); 
    if(redirectto) { 
     location.href = redirectto; 
    } 
}); 
Các vấn đề liên quan