2012-11-17 40 views
6

Tôi đang thực hiện cuộc gọi ajax đến máy chủ. Mã tôi cần chạy có thể được chia thành 3 nhóm.cách chạy javascript trong khi đợi cuộc gọi lại ajax

  1. Mã mà cần phải chạy trước khi in cuộc gọi ajax thực hiện (chuẩn bị đối tượng json đi đến máy chủ)
  2. Mã mà cần phải được chạy sau khi cuộc gọi ajax đã trở lại (sử dụng những gì đã được gửi trở lại từ máy chủ)
  3. Mã cần được chạy giữa thời gian người dùng nhấn nút và thời gian mọi thứ được thực hiện. Mã này không cần đối tượng json trả về.

Sẽ là lý tưởng khi chạy mã trong nhóm 3 sau khi thực hiện cuộc gọi ajax và trước khi kết quả quay lại để có được trải nghiệm và hiệu suất tốt nhất cho người dùng.

Việc này có thể thực hiện được không?

Làm cách nào?

+1

bạn đã thử đọc tài liệu chưa ?? Có giải thích cho tất cả các trường hợp của bạn http://api.jquery.com/jQuery.ajax/ – charlietfl

Trả lời

9

Rất đơn giản:

function someFunction() { 
    //1. code that needs to run before ajax 
    $.ajax({...}).done(function() { 
     //2. code that needs to be run after the ajax call has returned 
    }); 
    //3. code that needs to be run between the time the user presses 
    // a button and the time everything is done. 
} 

này hoạt động vì JavaScript là đồng bộ trong thực hiện (trừ khi người lao động đang được sử dụng, nhưng đó là không liên quan đến vấn đề cụ thể này). Bit đầu tiên của mã sẽ chạy, sau đó cuộc gọi ajax sẽ yêu cầu trình duyệt bắt đầu một yêu cầu XHR, nhưng someFunction chưa hoàn thành, do đó, nó sẽ tiếp tục thực hiện đồng bộ.

Khi hoàn tất someFunction, luồng điều khiển sẽ được mở ra cho bất kỳ sự kiện không đồng bộ nào xảy ra, cuối cùng dẫn đến cuộc gọi lại done.

Để công bằng, lập trình hướng sự kiện không đồng bộ là điều không dễ đối với hầu hết mọi người để bao quanh đầu. Thật dễ dàng để mất theo dõi những gì mã được cho là xảy ra vào thời điểm nào.

Dưới đây là một ví dụ dễ dàng thực thi như thế nào không đồng bộ hành vi hoạt động:

(function() { 
    alert(1); 
    setTimeout(function() { 
     alert(2); 
    }, 0); //note the 0ms delay 
    alert(3); 
}()); 

Trình tự các cảnh báo sẽ 1, 3, 2. setTimeout sẽ không gọi lại gọi lại đồng bộ vì nó phụ thuộc vào thời gian chờ định trước, vì vậy ngay cả khi không có thời gian trôi qua, nó vẫn phải đợi hàm hiện tại kết thúc trước khi nó có thể tiếp tục.

+0

+1 - Đây là điều mà nhiều nhà phát triển gặp khó khăn trong việc nắm bắt. – dtbarne

+0

Có phải '// 3' thực sự được bảo đảm để chạy trước' // 2' không? Nói '// 3' chứa rất nhiều hàm mất nhiều thời gian để tính toán/hoàn thành, không thể' // 2' về mặt lý thuyết nhảy vào ngăn xếp cuộc gọi tại bất kỳ thời điểm nào trong khi thực hiện bất kỳ điều gì trong '// 3'? Tôi không có nghĩa là cuộc gọi khốc liệt, tôi chỉ nghĩ rằng vì '// 2' là sự kiện thúc đẩy sự kiện có thể bắn vào bất kỳ điểm nào trong quá trình thực thi. – Jan

+0

@Jan, việc "kích hoạt" sự kiện async chỉ đơn giản là thêm một lệnh gọi hàm vào luồng thực thi * queue *. Hàng đợi chuyển sang hàm gọi tiếp theo chỉ khi các hàm đã xếp hàng trước đó đã hoàn thành việc thực hiện xong. Không thể xen kẽ các cuộc gọi chức năng trừ khi chúng sử dụng rõ ràng luồng đa luồng như với công nhân. – zzzzBov

0

Thực hiện cuộc gọi ajax khi phản ứng với sự kiện khách hàng hoặc trong bất kỳ trường hợp nào khác cho phép bạn chỉ định mã trong callbacks cũng như mã thực thi ngay sau khi mã ajax được tạo (không phải trong cuộc gọi lại).

Ví dụ:

// Code before the ajax call is made 
$.ajax({ 
    params, //other key values such as data 
    success: function (data) { 
     // one of the possible callbacks 
    } 
}); 
// Code executed immediately after ajax call is performed 
// This is executed before or after the callback is complete 
// In most cases it's before 

Vì vậy, bất cứ điều gì được thực hiện trước khi cuộc gọi ajax được làm bằng được đảm bảo để thực hiện trước đó. Bất cứ điều gì ngay lập tức sau khi cuộc gọi ajax gần như được đảm bảo thực hiện trước khi gọi lại được gọi. Cuộc gọi lại được đảm bảo thực thi sau khi máy chủ trả về một phản hồi.

+0

"Điều này được thực hiện trước hoặc sau khi hoàn thành gọi lại", tôi sẽ downvote điều này, như callbacks không thể xảy ra trước khi nó hoàn thành, nhưng sau đó tôi nhớ nó có thể có một cuộc gọi lại đồng bộ nếu nó được sử dụng như một tùy chọn . Tôi không chắc tôi thích cách bạn đã nói nó, vì nó ngụ ý rằng một cuộc gọi lại không đồng bộ có thể xảy ra trước khi luồng điều khiển được phát hành, điều đó sẽ không xảy ra. – zzzzBov

+0

@zzzzBov Bạn cũng có thể có mã async sau mã không đồng bộ. Vì vậy, nó không đảm bảo thực thi trước khi gọi lại đầu tiên. Đây là lý do tại sao câu trả lời của tôi là như vậy. Vui lòng chỉnh sửa nếu bạn nghĩ rằng bạn có thể cải thiện câu trả lời của tôi :) –

+0

việc gọi mã async (chẳng hạn như 'setTimeout (fn, delay)') sẽ thực thi trước khi bất kỳ cuộc gọi lại không đồng bộ nào có thể xảy ra. Sau khi hàm được thực hiện, bất kỳ hàm xếp hàng nào sẽ được thực hiện theo thứ tự mà chúng được gọi. Ví dụ, có thể là cuộc gọi lại 'success' sẽ sử dụng dữ liệu được lưu trong bộ nhớ cache, và xếp hàng gọi lại ngay lập tức, nó vẫn sẽ được đảm bảo xảy ra * sau * chức năng hiện đang thực thi đã kết thúc. – zzzzBov

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