2009-11-04 35 views
5

Tôi đang chạy xác thực trên dữ liệu biểu mẫu, chẳng hạn khi ai đó nhấn nút gửi, nó sẽ kiểm tra nội dung của biểu mẫu trước tiên. Một số trường (có thể bằng không, có thể nhiều hơn một, tùy thuộc vào trang) có những thứ như mã duy nhất yêu cầu kiểm tra với máy chủ trước. Tôi đang chạy một yêu cầu không đồng bộ đến máy chủ, yêu cầu này chỉ phản hồi 'ok' hoặc 'taken' cho mỗi trường. Nếu bất kỳ trường nào có lỗi, trang sẽ không gửi.jQuery AJAX: thu thập nhiều kết quả không đồng bộ

Một mặt, điều này sẽ không đồng bộ: nó sẽ tiếp tục xác thực phần còn lại của các trường biểu mẫu trong khi yêu cầu đó đang được xử lý, bao gồm kích hoạt các yêu cầu khác. Nếu cuộc gọi được thực hiện đồng bộ, thì nó sẽ làm chậm phản hồi về các trường sau.

Mặt khác, tôi muốn đảm bảo tất cả yêu cầu xác thực đã trả về (hoặc hết thời gian) trước khi trả lời có hoặc không cho phương thức validate() và cho phép gửi tiếp tục hay không. Vì vậy, nếu có hai trường cần xác thực thì phương thức validate() sẽ kích hoạt hai yêu cầu AJAX đó, xử lý phần còn lại của các trường và sau đó đợi cho đến khi hai yêu cầu đó được trả lại trước khi quay trở lại.

Tôi có thể đạt được điều này với một số giải pháp homebaked xấu xí (có thể liên quan đến một mảng các id ngẫu nhiên đại diện cho các yêu cầu đang tiến hành hoặc một cái gì đó), nhưng trước khi tôi làm là có bất kỳ chức năng, plugin hoặc kỹ thuật chuẩn nào sử dụng thay thế?


Làm rõ

Những gì tôi nghĩ tôi cần là làm cho sự chờ đợi mã cho kết quả từ một hoặc không đồng bộ hơn các yêu cầu trước khi tiến hành một phương pháp. Điều này không giống như gọi lại, bởi vì kết quả của phương thức này phụ thuộc vào kết quả của các yêu cầu. Nó không giống như yêu cầu đồng bộ vì có thể có nhiều hơn một trong số chúng.

Tôi đang sử dụng này để kiểm tra hình thức trước khi trình:

$("form").submit(function() { 
    return validate($(this)); 
}); 

Nếu phương pháp validate() trả về false, thì hình thức không nộp. validate() hilights bất kỳ trường nào không được chấp nhận. Đối với các trường bình thường, validate() trông giống như thế này (phiên bản bao la đơn giản, nếu không có sự phản hồi):

function validate(form) { 
    resetWarnings(form); 
    var ok = true; 

    // required fields 
    form.find("input.required").each(function() { 
     var field = $(this); 
     if (field.val() === "") { 
      ok = false; 
     } 
     return this; // meaningless in this case but a good habit to keep 
    }); 

    // fields that matches a pattern 
    form.find("input.pattern").each(function() { 
     var field = $(this); 
     var pattern = field.data("pattern"); 
     if (!field.val().match(pattern)) { 
      ok = false; 
     } 
     return this; 
    }); 

    // various other rules for other sorts of field 
    ... 

    return ok; 
} 

Đối với các trường AJAX nó giống như này:

form.find("input.lookup").each(function() { 
     var field = $(this); 
     var url = field.data("lookup"); 
     $.ajax({ 
      url: url, 
      data: { code: field.val() }, 
      success: function (result) { 
       if (result === "taken") { 
        ok = false; 
       } 
      } 
     } 
    }); 

Nhưng tất nhiên, validate() đã hoàn thành trước phương thức thành công được gọi. Vì vậy, nếu tôi có thể làm cho nó chờ đợi cho đến khi ajax đã được hoàn thành (hoặc thành công hoặc lỗi) trước khi trở về, tôi có thể nhận được kết quả đúng và ngừng các hình thức được gửi. Và nếu tôi thực hiện ajax đồng bộ, thì toàn bộ phương thức dừng lại cho đến khi nó được thực hiện, điều đó là sai.


Hơn nữa nghĩ

Với mô hình luồng Javascript (mà là để nói không có gì cả), là những gì tôi đang yêu cầu về mặt kỹ thuật không thể?

Trả lời

1

Nếu tôi hiểu chính xác bạn, bạn muốn kiểm tra xem các giá trị (1 ..*) được nhập vào một biểu mẫu là duy nhất, khi người dùng nhấn nút gửi trước khi thực hiện bài đăng trên biểu mẫu. Nếu đúng như vậy, tôi sẽ tạo một mảng các trường và giá trị JSON và gửi tất cả cùng một lúc - vì vậy bạn chỉ đang đợi một câu trả lời. Điều này sẽ khá dễ dàng bằng cách sử dụng hàm jQuery 'each' và sử dụng jQuery ajax.

Sau đó, bạn có thể kiểm tra kết quả duy nhất trước khi đăng biểu mẫu.

Có thể không cần phải nói, nhưng đảm bảo bạn lặp lại cùng một máy chủ xác thực khi bạn đã đăng để tránh điều kiện cuộc đua với những người dùng khác.

Bạn có thể xác thực các trường riêng lẻ khi người dùng hoàn thành biểu mẫu và lưu trữ kết quả, nhưng điều này sẽ trở nên thú vị hơn (vì lý do khả năng mở rộng bạn nên xem xét băng thông) và bạn tự mình không có xác thực .

+0

Nó không phải là một chuỗi các trường duy nhất giống nhau, nhưng khả năng nhiều hơn một trường trên biểu mẫu cần kiểm tra phía máy chủ - tại các URL khác nhau, so với các kiểm tra khác nhau. Trong thực tế, bit nhiều không phải là điều quan trọng - nó làm cho phương thức validate() chờ kết quả không đồng bộ. Lý do duy nhất tôi nhấn mạnh rằng có thể có nhiều hơn một trường để thực hiện một cuộc gọi đồng bộ duy nhất không phải là một câu trả lời hợp lệ. –

+0

Xem làm rõ. –

+0

Tôi không chắc chắn những gì tôi yêu cầu là có thể. Xác thực các trường khi người dùng hoàn tất biểu mẫu có thể sẽ là cách duy nhất. –

0

Làm thế nào về việc sử dụng .ajaxStop:

$(document).ajaxStop(function() { 
    $(this).unbind("ajaxStop"); 
    // run validate method here 
    }); 
    //run asynchronous validations here 

Lưu ý rằng unbind là cần thiết nếu validate() tự nó liên quan đến một cuộc gọi AJAX.

3

Với jQuery 1.5+ cách tốt nhất để thu thập dữ liệu kết quả từ nhiều yêu cầu không đồng bộ là sử dụng đối tượng Trì hoãn đại diện cho các yêu cầu này với trạng thái của chúng và hàm wrapper $ .when (...). someRequestFailedCallback())

Điều đó giúp tránh sử dụng nhiều chức năng gọi lại lồng nhau giúp mã của bạn sạch hơn và dễ bảo trì hơn.

JavaScript/jQuery dụ:

function ajax1() { return $.ajax({ url: 'server1.php' }) } 
function ajax2() { return $.ajax({ url: 'server2.php' }) } 

$.when(ajax1(), ajax2()).then(
    function() { 
     // ajax1 AND ajax2 succeeded 
    }, 
    function() { 
     // ajax1 OR ajax2 succeeded 
    } 
); 

Kiểm tra để biết thêm tài liệu và các ví dụ ở đây:

+0

Có cách nào để làm điều này mà không biết trước bao nhiêu đối tượng trì hoãn bạn sẽ có? Ví dụ: khi nhiều yêu cầu là do tách một mảng lớn có chiều dài không xác định thành các đoạn có độ dài không đổi? – learn2day

Các vấn đề liên quan