2012-03-10 15 views
10

thể trùng lặp:
How can I get jQuery to perform a synchronous, rather than asynchronous, AJAX request?
how to wait for an ajax call to returncách chính xác để chờ ajax trở lại (tôi không muốn sử dụng bộ xử lý thành công.)

Nghe tôi ra ngoài. Tôi hoàn toàn hiểu đoạn mã này.

$.getJSON(someURL, function(data){ 
    //do something with my data 
}) 
.success(function() { 
    //Call what you want on success 
}) 

Điều này có vẻ tốt nếu tôi chỉ cần thực hiện một hành động khá tĩnh. Tuy nhiên, những gì nếu tôi muốn trở thành ít bị hạn chế, ví dụ này

function my_func(){ 
    $.getJSON(someURL, function(data){ 
     //do something with my data... like modify an array or the dom 
    }) 
} 

Bây giờ tài xế

my_func(); 
//Now I want to call a function that relies on the data that my_func brought into the script. 

Có điều gì sai trái với cách tôi đang viết mã kịch bản của tôi nếu tôi muốn làm điều đó như thế này? Hoặc tôi chỉ thiếu một số phương pháp được xây dựng tuyệt vời?

+0

Nhưng đó là những gì gọi lại thành công là ... bất kỳ lý do cụ thể nào tại sao nó sẽ không hoạt động cho bạn? Bạn cần ít bị hạn chế hơn theo cách nào? –

+0

sử dụng cờ 'async: false'. – kirilloid

+0

"Hay tôi chỉ thiếu một số phương pháp được xây dựng tuyệt vời?" Yup: http://api.jquery.com/jQuery.ajax/ với 'async: false' – PeeHaa

Trả lời

13

Tôi thấy hai cách jQuery-ish có thể có.

Đầu tiên sẽ được sử dụng một callback có thể được truyền cho my_func:

function my_func(callback) { 
    $.getJSON(someUrl, function(data) { 
     // ...do stuff ... 
     if ($.isFunction(callback)) { callback(data); } 
    }); 
} 

my_func(function(data) { 
    // ..do more stuff.. 
}); 

Cách thứ hai là tạo ra một sự kiện tùy chỉnh mà được kích hoạt bên trong my_func và có thể được nghe từ bên ngoài:

function my_func() { 
    $.getJSON(someUrl, function(data) { 
     $(document).triggerHandler('my_func:data-received', [data]); 
    }); 
} 

$(document).on('my_func:data-received', function(event, data) { 
    // ...do stuff... 
}); 

my_func(); 

Tôi khuyên bạn chỉ nên sử dụng async: false chỉ khi thật cần thiết.


Just another (rất gọn gàng) cách để đối phó với điều này là đối tượng jQuery.Deferred:

function my_func() { 
    var d = new $.Deferred(); 
    $.getJSON(someUrl, function(data) { 
     d.resolve(data); 
    }); 
    return d; 
} 

my_func().done(function(data) { 
    // ...do stuff... 
}); 

Chức năng của bạn trả về một đối tượng cho phép đăng ký callbacks. Trong chức năng bạn chỉ cần đảm bảo gọi resolve để gọi tất cả các trình xử lý gọi lại done đã đăng ký.

+0

Trì hoãn! Tôi biết tôi đã nghe về điều gì đó về điều đó. Tôi nghĩ rằng tôi đã nghe một bài phát biểu về chủ đề này trong những năm qua jquery hội nghị thượng đỉnh .. Tôi nên đi tìm các bản ghi âm. Woohoo! – Jake

1

Có thể bạn đã chuyển hàm của mình chạy trên dữ liệu đến my_func().

//     v--------receive a callback 
function my_func(callback_fn){ 

    $.getJSON(someURL, callback_fn); // use the callback as the getJSON callback 

} 

sau đó ...

my_func(function(data) { 
    // do something with data 
}) 

... hoặc nếu chức năng bạn muốn gọi là một hàm có tên, sau đó tất nhiên bạn muốn vượt qua nó bằng tên ...

my_func(someOtherFunction) 

Dù bằng cách nào, chức năng my_func() của bạn sẽ sử dụng chức năng này làm cuộc gọi lại đến cuộc gọi $.getJSON, cuộc gọi sẽ gọi khi dữ liệu đến.

+0

Bạn biết đó là một bản dupe chính xác của một bản dupe của một quyền dupe? – PeeHaa

+0

@PeeHaa: Chắc chắn rồi. Gần như mọi thứ đều là một sự lừa đảo. –

+0

Yup đó là lý do tại sao chúng tôi có gần như tùy chọn dupe chính xác. – PeeHaa

2

Sau đó có các đối tượng XHR:

var jqXHR = $.getJSON(someURL); 

Bạn có thể truy cập nó bất cứ nơi nào sau khi nó được định nghĩa:

jqXHR.always(function() { 
    alert('JSON IS COMLETE'); 
}); 

jqXHR.done(function(data) { 
    //do something with the returned data if success! 
}); 

jqXHR.fail(function(jqXHR, textStatus) { 
    alert('JSON FAILED : '+textStatus); 
}); 

FIDDLE

Bạn thậm chí có thể làm một cái gì đó như thế này:

$("#button").on('click', Myfunc); 

function Myfunc() { 
    var jqXHR = runAjax(); 
     jqXHR.done(function(data) { 
      alert($.parseJSON(data)); 
      $("#result").html('JSON IS DONE'); 
     }); 
} 

function runAjax() { 
    return $.getJSON(someURL); 
} 

FIDDLE

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