2012-06-07 30 views
13

Tôi vừa mới trải qua 3 giờ gỡ lỗi một chút mã duy nhất để tìm thấy nó là do tôi giả định rằng trình tự thực hiện các đoạn mã sau là tuyến tính: -

$.ajax({ajax options}); 
console.log('I was assuming this would execute once the ajax request was complete'); 

Đây không phải là lần đầu tiên điều này đã gây ra vấn đề cho tôi và tôi đã tự hỏi lý do của hành vi này là gì?

Có phải mọi yêu cầu ajax không giữ thực thi tập lệnh khác có thể không liên quan đến yêu cầu ajax không?

+18

Chữ cái đầu tiên 'A' trong' AJAX' là viết tắt của không đồng bộ. – Gareth

+3

Bạn có thể đặt tùy chọn 'async: true'. Các yêu cầu đồng bộ có thể tạm thời khóa trình duyệt, vô hiệu hóa bất kỳ hành động nào trong khi yêu cầu đang hoạt động. Không được khuyến khích. – jasssonpet

+0

@Gareth Tôi đã biết rằng A đứng không đồng bộ, tuy nhiên tôi luôn nghĩ rằng điều này đề cập đến thực tế là yêu cầu được thực hiện mà không cần tải lại trang, tức là yêu cầu http 'cha mẹ' một lần nữa, do đó trang đó là 'không được đồng bộ hóa' với yêu cầu http ban đầu đã phân phối trang. – rgvcorley

Trả lời

12

Hầu hết các câu trả lời khác đều trả lời cách giải quyết vấn đề này. Tôi muốn xem xét, rất ngắn gọn, tại lý do tại sao không đồng bộ là tốt trong trường hợp này.

Thực tế, hầu hết Javascript trong trình duyệt là không đồng bộ. Lấy ví dụ, mã này:

document.getElementById('foo').onclick = function() { 
    alert('foo clicked'); 
}; 
document.getElementById('bar').onclick = function() { 
    alert('bar clicked'); 
}; 

Điều gì sẽ chạy trước? Bạn không biết, vì sự bất thường vốn có của mô hình trình duyệt (hoặc trên thực tế hầu hết mã hướng sự kiện). Bạn chạy mã khi một sự kiện xảy ra. Bạn thiết lập tài liệu, sau đó chờ sự kiện xảy ra và mã của bạn có thể được thực hiện bằng tất cả các loại đơn đặt hàng khác nhau, tùy thuộc vào sự kiện nào xảy ra trước tiên. Mã Javascript cần được thực hiện trong toàn bộ thời gian tồn tại của trang, không chỉ khi được tạo lần đầu tiên.

Vì vậy, nói chung Lập trình Javascript (hoặc ít nhất, lập trình Javascript vượt mức đơn giản nhất) thường sẽ không đồng bộ. Hơn nữa, nó làm cho rất nhiều ý nghĩa cho các yêu cầu HTTP được không đồng bộ là tốt.

Trước tiên, như bạn ngụ ý trong câu hỏi của mình, làm cho mã đồng bộ sẽ chặn thực thi. Đó là để nói, có thể bạn không muốn tạo một hoạt ảnh chờ hai giây để bắt đầu vì bạn đang thực hiện một yêu cầu HTTP thêm hai dòng nữa. Thời gian đáp ứng của máy chủ có thể là (a) bất thường và (b) chậm, do đó, không có ý nghĩa gì đối với việc thiết kế ứng dụng của bạn phụ thuộc vào tốc độ phản hồi của máy chủ của bạn.

Thứ hai và quan trọng hơn, người dùng của bạn sẽ không ngừng sử dụng trang vì tập lệnh của bạn đang thực hiện cuộc gọi AJAX. Người dùng của bạn không quan tâm. Người dùng của bạn có thể sẽ quan tâm rằng hành vi bình thường onscroll của bạn không hoạt động vì tập lệnh của bạn hiện được gắn với yêu cầu AJAX không liên quan. Để gắn liền với bản chất không đồng bộ của toàn bộ lập trình Javascript của trình duyệt, phần lớn các cuộc gọi HTTP sẽ không bị chặn, không đồng bộ.

+0

Đây chỉ là câu trả lời tôi đang tìm kiếm - bạn nói đúng đã không tìm kiếm giải pháp cho vấn đề (tôi đã biết rõ cách thực hiện yêu cầu đồng bộ) Tôi muốn biết TẠI SAO nó không đồng bộ, vì vậy thankyou rất nhiều! – rgvcorley

1

Để giữ lên AJAX hoàn thành, bạn cần phải đặt mã của bạn bên success: chức năng như dưới đây:

$.ajax({ 
    url: 'ajax/test.html', 
    success: function(data) { 
    // Do something after AJAX is completed. 
    console.log('I was assuming this would execute once the ajax request was complete'); 
    } 
}); 
0

$.ajax là một chức năng không đồng bộ và như vậy không đợi cho yêu cầu để hoàn thành, trước khi trở về. Thay vào đó, khi yêu cầu kết thúc, nó gọi các hàm gọi lại, bạn chỉ định bởi success và/hoặc error.

Nếu bạn thực sự cần một bahviour đồng bộ, bạn có thể đặt tùy chọn async thành sai. (xem docu). Nhưng trong trường hợp đó, hãy nhớ rằng toàn bộ giao diện người dùng bị đóng băng cho đến khi yêu cầu kết thúc!

10

vì ajax là không đồng bộ. nếu bạn muốn thực hiện một cái gì đó về sự thành công của cuộc gọi ajax, sử dụng các sự kiện thành công

$.ajax({ 
    url: 'yourserverpage.php', 
    success: function(data) { 

    alert('This will be executed only when ajax call is success /finished'); 
    } 
}); 

Asynchronous phương tiện?

Asynchronous I/O, hoặc non-blocking I/O, là một hình thức đầu vào/đầu ra chế biến cho phép xử lý khác để tiếp tục trước khi truyền đã finished.Asynchronous I/O được sử dụng để cải thiện thông lượng, độ trễ và/hoặc phản hồi.

+0

Ok, tuyệt vời - Tôi đã biết A là không đồng bộ, tuy nhiên tôi luôn nghĩ rằng điều này đề cập đến thực tế là yêu cầu được thực hiện mà không cần tải lại trang, (tức là yêu cầu http 'cha mẹ' lại) sau đó trang 'không được đồng bộ hóa' với yêu cầu http ban đầu đã phân phối trang. – rgvcorley

+0

thường mọi người sử dụng ajax để thực hiện cập nhật một phần mà không cần tải lại trang hoàn chỉnh (bạn có thể đã thấy trong facebook, twitter, stackoverflow vv ..) để cung cấp trải nghiệm người dùng tốt đẹp – Shyju

+0

... nhưng đó không phải là những gì không đồng bộ đến – rgvcorley

1

Bạn có thể làm thành công hoặc bạn cũng có thể sử dụng .done();

$.ajax({ajax options}).done(console.log('I was assuming this would execute once the ajax request was complete')); 
0

Như những người khác đã nói, ajax là viết tắt của Asynchronous JavaScript and XML. Điều đó đang được nói, bạn có thể làm một trong hai điều sau đây với jquerys ajax chức năng:

  1. Đặt "async" tùy chọn để sai, nếu bạn muốn cuộc gọi đến được đồng bộ. Điều này đúng theo mặc định. Xem tài liệu. Kể từ jQuery 1.8, việc sử dụng thuộc tính này không còn được dùng nữa.

  2. Cung cấp gọi lại "hoàn tất". Điều này sẽ xảy ra không đồng bộ theo mặc định. Đây là:

    Một hàm được gọi khi yêu cầu kết thúc (sau khi thành công và lỗi gọi lại được thực hiện).

  3. Cung cấp gọi lại "thành công". Điều này sẽ xảy ra không đồng bộ theo mặc định.Đây là:

    Một hàm sẽ được gọi nếu yêu cầu thành công.

+0

Tôi đã không hỏi làm thế nào để làm cho yêu cầu đồng bộ - Tôi đã hỏi tại sao nó không đồng bộ – rgvcorley

0

Đầu tiên Một trong AJAX là viết tắt của Asynchronous ; điều đó có nghĩa là các cuộc gọi AJAX được thực hiện ở chế độ nền và không giữ thực thi kịch bản cho đến khi chúng được hoàn tất. Điều này là khá nhiều bởi thiết kế.

Nếu bạn muốn chạy một số mã khi cuộc gọi kết thúc, bạn có thể vượt qua một hàm trong một hoặc nhiều các thông số sau:

$.ajax({ 
    // your other options 

    done: function(data, textStatus, jqXHR) { 
    alert('Success! I got the following data back: ' + data); 
    // this runs when the request has finished successfully 
    }, 

    fail: function(jqXHR, textStatus, errorThrown) { 
    alert('Oops, there was an error :('); 
    // this runs when the request has finished, but with an error 
    }, 

    always: function(jqXHR, textStatus) { 
    alert("OK, I'm done."); 
    // this runs when the call is finished, regardless 
    // of whether it has succeeded or not 
    } 

Mọi chi tiết, xem phần API: http://api.jquery.com/jQuery.ajax

+0

OMG, 6 câu trả lời khác trong khi tôi đang viết ... –

2

jQuery $.ajax() cung cấp 4 (sự kiện) tùy chọn mà bạn có thể sử dụng: beforeSend, success, error, và complete. Tôi nghĩ trong trường hợp của bạn, hoàn thành sẽ là câu trả lời đúng.

Ví dụ

$.ajax({ 
    url: someUrl, 
    //... 
    beforeSend: function(){ 
    console.log("I'm sending AJAX."); 
    //display loading? 
    }, 
    success: function(data){ 
    console.log('response: '+data); 
    }, 
    error: function(er){ 
    console.log(er.responseText); 
    }, 
    complete: function(){ 
    console.log("I'm done."); 
    //hide loading? 
    } 
}); 
0

lựa chọn khác là chỉ cần đặt async false

$.ajax({ 
    async : 'false', 
    other options 
}); 

Bằng cách này tuyên bố tiếp theo của bạn sẽ không được thực hiện cho đến khi tuyên bố $ .ajax kết thúc.

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