Có thể đặt async: false thành lệnh gọi $ .getJSON không


105

Có thể đặt async: falsekhi gọi $.getJSON()để cuộc gọi chặn thay vì không đồng bộ không?


1
Chỉ cần đặt mã của bạn trong khi gọi lại .... Có một lý do này không được chấp - đó là một ý tưởng tồi
Milney

1
@Milney - Rất lạ ... Chính thức, nó bị phản đối; thực sự, nó không phải là . Nếu nó thực sự không được dùng nữa, khả năng thực hiện lệnh gọi AJAX đồng bộ hoặc chuyển đổi $ ajax.setup sẽ bị loại bỏ trong jQuery 3. Trên thực tế, một lệnh gọi đồng bộ đôi khi rất hữu ích, chẳng hạn như khi khởi tạo các hình cầu với Dữ liệu JSON, khi bạn có các toàn cầu khác dựa trên lô đầu tiên. (Đóng gói quá trình khởi tạo toàn bộ trong hàm callback có thể là rất khó khăn trong điều kiện nhất định.)
Brice Coustillas

Tôi nghĩ rằng yêu cầu XHR đồng bộ hoặc mã Tái cấu trúc sẽ trả lời trường hợp này.
Chetabahana

Câu trả lời:


154

Bạn cần thực hiện cuộc gọi bằng cách sử dụng $.ajax()nó một cách đồng bộ, như sau:

$.ajax({
  url: myUrl,
  dataType: 'json',
  async: false,
  data: myData,
  success: function(data) {
    //stuff
    //...
  }
});

Điều này sẽ phù hợp với hiện đang sử dụng $.getJSON()như thế này:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});

23
Tôi nhận thấy phương thức tiện lợi $ .getJSON () hầu như không bao giờ hữu ích và luôn kết thúc bằng cách sử dụng $ .ajax ().
Jacob Marble

tôi có thể sử dụng cái này cho cuộc gọi POST không?
Hitesh

@hitesh vâng, bạn cũng sẽ thêm một type: 'POST'tùy chọn để biến nó thành một bài đăng - mặc dù bạn không muốn sử dụng async: falsetrừ khi bạn thực sự cần - nó sẽ khóa giao diện người dùng.
Nick Craver

1
'MyData' phải là gì trong trường hợp này? Khi tôi xóa dữ liệu: myData hoàn toàn hoạt động .. Khá mới với các cuộc gọi ajax!
nclsvh

2
Vừa mới gặp phải vấn đề mới sau: "Synchronous XMLHttpRequest bên ngoài công nhân đang trong quá trình bị xóa khỏi nền tảng web vì nó có tác động bất lợi đến trải nghiệm của người dùng cuối. (Đây là một quá trình lâu dài, mất nhiều năm.) Các nhà phát triển phải không được chuyển false cho đối số async khi đối tượng chung của đối tượng cài đặt mục nhập là đối tượng Window. Tác nhân người dùng được khuyến khích cảnh báo về cách sử dụng như vậy trong các công cụ dành cho nhà phát triển và có thể thử nghiệm với việc đưa ra ngoại lệ InvalidAccessError khi nó xảy ra. "
Ken Sharp

46

Cả hai câu trả lời đều sai. Bạn có thể. Bạn cần gọi

$.ajaxSetup({
async: false
});

trước cuộc gọi ajax json của bạn. Và bạn có thể đặt nó thành true sau khi gọi lại (nếu có các cách sử dụng ajax khác trên trang nếu bạn muốn chúng không đồng bộ)


1
Tôi chỉ đọc lại phần đó của tài liệu. Đây là phần nói về ajaxSetup: api.jquery.com/jQuery.ajaxSetup Và đây là các tùy chọn: api.jquery.com/jQuery.ajax Nó nói rõ ràng: "async Mặc định: true Theo mặc định, tất cả các yêu cầu được gửi không đồng bộ ( tức là điều này được đặt thành true theo mặc định). Nếu bạn cần các yêu cầu đồng bộ, hãy đặt tùy chọn này thành false. Các yêu cầu tên miền chéo và yêu cầu dataType: "jsonp" không hỗ trợ hoạt động đồng bộ. "JSONP không phải là JSON nên tôi vẫn nghĩ là mình ngay từ đầu. Tôi sẽ viết ví dụ sau khi tôi có thời gian.
velja

7
Đây là một nhận xét muộn nhưng ... câu trả lời "cả hai" đều sai? Tôi thấy câu trả lời từ @Nick Craver vừa có thể chấp nhận được vừa không "gây rối" với cài đặt AJAX toàn cầu (nếu các yêu cầu khác được kích hoạt cùng lúc)
scunliffe

1
Nó hoạt động, nhưng điều này sẽ áp dụng cho tất cả các yêu cầu ajax mà bạn thực hiện trong trang. Vì vậy, tôi sẽ phản đối vì tôi không muốn giới thiệu nó
GabrielBB

3
Đây là một câu trả lời chất lượng rất thấp
Brian Webster

1
-1: Làm cho mọi thứ đồng bộ có thể tốn kém. Bạn chắc chắn nên làm điều này trên cơ sở mỗi cuộc gọi trừ khi dự án của bạn hoàn toàn yêu cầu nó mọi lúc. Câu trả lời của bạn gợi ý rằng bạn định cấu hình toàn cầu tất cả các lệnh gọi đến $.ajax(và các trình bao bọc viết tắt tiếp theo $.getJSON, tức là $.get, v.v.) để được đồng bộ. Hơn nữa, tài liệu thậm chí còn đề xuất không sử dụng điều này: "Mô tả: Đặt giá trị mặc định cho các yêu cầu Ajax trong tương lai. Việc sử dụng nó không được khuyến khích."
Carrie Kendall

18

Tôi nghĩ rằng cả hai bạn đều đúng. Câu trả lời sau hoạt động tốt nhưng nó giống như thiết lập một tùy chọn chung, vì vậy bạn phải làm như sau:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });

10

Trong trường hợp của tôi, Jay D đúng. Tôi phải thêm điều này trước khi cuộc gọi.

$.ajaxSetup({
    async: false
});

Trong mã trước đây của tôi, tôi có cái này:

var jsonData= (function() {
    var result;
    $.ajax({
        type:'GET',
        url:'data.txt',
        dataType:'json',
        async:false,
        success:function(data){
            result = data;
        }
    });
    return result;
})();
alert(JSON.stringify(jsonData));

Nó hoạt động tìm. Sau đó, tôi thay đổi thành

var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));

Cảnh báo là không xác định.

Nếu tôi thêm ba dòng đó, cảnh báo sẽ hiển thị lại dữ liệu.

$.ajaxSetup({
    async: false
});
var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));

1

Nếu bạn chỉ cần awaittránh mã lồng nhau:

let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));

0

Tôi không nghĩ rằng bạn có thể đặt tùy chọn đó ở đó. Bạn sẽ phải sử dụng jQuery.ajax () với các tham số thích hợp (về cơ bản getJSON cũng chỉ gói lời gọi đó thành một API dễ dàng hơn).


0

Cuộn ví dụ của riêng bạn

function syncJSON(i_url, callback) {
  $.ajax({
    type: "POST",
    async: false,
    url: i_url,
    contentType: "application/json",
    dataType: "json",
    success: function (msg) { callback(msg) },
    error: function (msg) { alert('error : ' + msg.d); }
  });
}

syncJSON("/pathToYourResouce", function (msg) {
   console.log(msg);
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.