Javascript Làm cách nào để trả về phản hồi từ cuộc gọi không đồng bộ?

  • 2/6/2020 6:21:56 AM bởi admin
  • 0 câu trả lời

Câu hỏi

Tôi có một hàm foo tạo một yêu cầu Ajax. Làm thế nào tôi có thể trả lại phản hồi từ foo?

Tôi đã thử trả về giá trị từ cuộc successgọi lại cũng như gán phản hồi cho một biến cục bộ bên trong hàm và trả về giá trị đó, nhưng không có cách nào thực sự trả về phản hồi.


function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- I tried that one as well
        }
    });

    return result;
}

var result = foo(); // It always ends up being `undefined`.
3 câu trả lời, 0 Đã được chấp nhận

admin posted 2/6/2020 6:23:32 AM

Vấn đề Chữ A trong Ajax là viết tắt của không đồng bộ . Điều đó có nghĩa là gửi yêu cầu (hay đúng hơn là nhận phản hồi) được đưa ra khỏi luồng thực thi thông thường. Trong ví dụ của bạn, $.ajaxtrả về ngay lập tức và câu lệnh tiếp theo return result;, được thực thi trước khi hàm bạn chuyển qua khi successgọi lại thậm chí được gọi.

Đây là một sự tương tự mà hy vọng làm cho sự khác biệt giữa dòng chảy đồng bộ và không đồng bộ rõ ràng hơn:

Đồng bộ Hãy tưởng tượng bạn gọi điện thoại cho một người bạn và yêu cầu anh ta tìm kiếm thứ gì đó cho bạn. Mặc dù có thể mất một lúc, bạn đợi điện thoại và nhìn chằm chằm vào không gian, cho đến khi bạn của bạn đưa ra câu trả lời mà bạn cần.

Điều tương tự cũng xảy ra khi bạn thực hiện một cuộc gọi hàm chứa mã "bình thường":

function findItem() { var item; while(item_not_found) { // search } return item; }

var item = findItem();

// Do something with item doSomethingElse(); Mặc dù findItemcó thể mất nhiều thời gian để thực thi, bất kỳ mã nào đến sau var item = findItem();phải đợi cho đến khi hàm trả về kết quả.

Không đồng bộ Bạn gọi lại cho bạn của bạn vì lý do tương tự. Nhưng lần này bạn nói với anh ấy rằng bạn đang vội và anh ấy nên gọi lại cho bạn trên điện thoại di động của bạn. Bạn cúp máy, rời khỏi nhà và làm bất cứ điều gì bạn dự định làm. Khi bạn của bạn gọi lại cho bạn, bạn đang xử lý thông tin anh ấy đã cung cấp cho bạn.

Đó chính xác là những gì xảy ra khi bạn thực hiện một yêu cầu Ajax.

findItem(function(item) { // Do something with item }); doSomethingElse(); Thay vì chờ phản hồi, việc thực thi tiếp tục ngay lập tức và câu lệnh sau khi lệnh gọi Ajax được thực thi. Để nhận được phản hồi cuối cùng, bạn cung cấp một chức năng được gọi sau khi nhận được phản hồi, gọi lại (có thông báo gì không? Gọi lại ?). Bất kỳ câu lệnh nào đến sau cuộc gọi đó được thực thi trước khi gọi lại.

Các giải pháp) Nắm bắt bản chất không đồng bộ của JavaScript! Mặc dù các hoạt động không đồng bộ nhất định cung cấp các đối tác đồng bộ ("Ajax"), nhưng nói chung, không khuyến khích sử dụng chúng, đặc biệt là trong bối cảnh trình duyệt.

Tại sao nó xấu khi bạn hỏi?

JavaScript chạy trong luồng UI của trình duyệt và bất kỳ quá trình chạy dài nào cũng sẽ khóa UI, khiến nó không phản hồi. Ngoài ra, có giới hạn trên về thời gian thực hiện đối với JavaScript và trình duyệt sẽ hỏi người dùng có tiếp tục thực hiện hay không.

Tất cả điều này là trải nghiệm người dùng thực sự xấu. Người dùng sẽ không thể biết liệu mọi thứ có hoạt động tốt hay không. Hơn nữa, hiệu quả sẽ tồi tệ hơn đối với người dùng có kết nối chậm.

Sau đây chúng ta sẽ xem xét ba giải pháp khác nhau, tất cả đều được xây dựng chồng lên nhau:

Hứa hẹn vớiasync/await (ES2017 +, khả dụng trong các trình duyệt cũ hơn nếu bạn sử dụng bộ chuyển mã hoặc trình tái tạo) Gọi lại (phổ biến trong nút) Hứa vớithen() (ES2015 +, khả dụng trong các trình duyệt cũ hơn nếu bạn sử dụng một trong nhiều thư viện hứa hẹn) Cả ba đều có sẵn trong các trình duyệt hiện tại và nút 7+.

ES2017 +: Hứa hẹn với async/await Phiên bản ECMAScript được phát hành năm 2017 đã giới thiệu hỗ trợ cấp cú pháp cho các chức năng không đồng bộ. Với sự giúp đỡ của asyncvà await, bạn có thể viết không đồng bộ theo "kiểu đồng bộ". Mã vẫn không đồng bộ, nhưng dễ đọc / dễ hiểu hơn.

async/awaitxây dựng dựa trên lời hứa: một asyncchức năng luôn trả về một lời hứa. await"hủy bỏ" một lời hứa và dẫn đến giá trị của lời hứa đã được giải quyết hoặc ném lỗi nếu lời hứa bị từ chối.

Quan trọng: Bạn chỉ có thể sử dụng awaitbên trong một asyncchức năng. Ngay bây giờ, cấp cao nhất awaitchưa được hỗ trợ, do đó bạn có thể phải tạo một IIFE async ( Biểu thức hàm được gọi ngay lập tức ) để bắt đầu một asyncbối cảnh.

Bạn có thể đọc thêm về asyncvà awaittrên MDN.

Dưới đây là một ví dụ được xây dựng dựa trên độ trễ trên:


// Using 'superagent' which will return a promise.
var superagent = require('superagent')

// This is isn't declared as `async` because it already returns a promise
function delay() {
  // `delay` returns a promise
  return new Promise(function(resolve, reject) {
    // Only `delay` is able to resolve or reject the promise
    setTimeout(function() {
      resolve(42); // After 3 seconds, resolve the promise with value 42
    }, 3000);
  });
}


async function getAllBooks() {
  try {
    // GET a list of book IDs of the current user
    var bookIDs = await superagent.get('/user/books');
    // wait for 3 seconds (just for the sake of this example)
    await delay();
    // GET information about each book
    return await superagent.get('/books/ids='+JSON.stringify(bookIDs));
  } catch(error) {
    // If any of the awaited promises was rejected, this catch block
    // would catch the rejection reason
    return null;
  }
}

// Start an IIFE to use `await` at the top level
(async function(){
  let books = await getAllBooks();
  console.log(books);
})();

Phiên bản trình duyệt và nút hiện tại hỗ trợ async/await. Bạn cũng có thể hỗ trợ các môi trường cũ hơn bằng cách chuyển đổi mã của mình sang ES5 với sự trợ giúp của trình tái tạo (hoặc các công cụ sử dụng trình tái tạo, chẳng hạn như Babel ).

Để các hàm chấp nhận cuộc gọi lại Một cuộc gọi lại chỉ đơn giản là một chức năng được chuyển đến một chức năng khác. Hàm khác có thể gọi hàm được truyền bất cứ khi nào nó sẵn sàng. Trong ngữ cảnh của một quy trình không đồng bộ, cuộc gọi lại sẽ được gọi bất cứ khi nào quá trình không đồng bộ được thực hiện. Thông thường, kết quả được chuyển đến cuộc gọi lại.

Trong ví dụ của câu hỏi, bạn có thể foochấp nhận gọi lại và sử dụng nó làm successcuộc gọi lại. Vậy đây

var result = foo(); // Code that depends on 'result' trở thành

foo(function(result) { // Code that depends on 'result' }); Ở đây chúng tôi đã định nghĩa hàm "nội tuyến" nhưng bạn có thể vượt qua bất kỳ tham chiếu chức năng nào:


function myCallback(result) {
    // Code that depends on 'result'
}

foo(myCallback);
foo chính nó được định nghĩa như sau:

function foo(callback) {
    $.ajax({
        // ...
        success: callback
    });
}

callbacksẽ đề cập đến chức năng chúng ta chuyển đến fookhi chúng ta gọi nó và chúng ta chỉ cần chuyển nó sang success. Tức là một khi yêu cầu Ajax thành công, $.ajaxsẽ gọi callbackvà chuyển phản hồi cho cuộc gọi lại (có thể được gọi bằng result, vì đây là cách chúng tôi đã xác định cuộc gọi lại).

Bạn cũng có thể xử lý phản hồi trước khi chuyển nó đến cuộc gọi lại:

function foo(callback) { $.ajax({ // ... success: function(response) { // For example, filter the response callback(filtered_response); } }); } Viết mã bằng cách gọi lại dễ dàng hơn có vẻ. Rốt cuộc, JavaScript trong trình duyệt được điều khiển rất nhiều sự kiện (các sự kiện DOM). Nhận được phản hồi Ajax không gì khác ngoài một sự kiện. Khó khăn có thể phát sinh khi bạn phải làm việc với mã của bên thứ ba, nhưng hầu hết các vấn đề có thể được giải quyết chỉ bằng cách suy nghĩ thông qua dòng ứng dụng.

ES2015 +: Hứa với sau đó () Các Promise API là một tính năng mới của ECMAScript 6 (ES2015), nhưng nó có tốt hỗ trợ trình duyệt rồi. Ngoài ra còn có nhiều thư viện triển khai API Promise tiêu chuẩn và cung cấp các phương thức bổ sung để dễ dàng sử dụng và cấu thành các chức năng không đồng bộ (ví dụ như bluebird ).

Lời hứa là container cho các giá trị trong tương lai . Khi lời hứa nhận được giá trị (nó đã được giải quyết ) hoặc khi nó bị hủy ( bị từ chối ), nó sẽ thông báo cho tất cả "người nghe" của mình, những người muốn truy cập giá trị này.

Ưu điểm so với các cuộc gọi lại đơn giản là chúng cho phép bạn tách mã của bạn và chúng dễ dàng soạn thảo hơn.

Đây là một ví dụ đơn giản về việc sử dụng một lời hứa:

function delay() { // delay returns a promise return new Promise(function(resolve, reject) { // Only delay is able to resolve or reject the promise setTimeout(function() { resolve(42); // After 3 seconds, resolve the promise with value 42 }, 3000); }); }

delay() .then(function(v) { // delay returns a promise console.log(v); // Log the value once it is resolved }) .catch(function(v) { // Or do something else if it is rejected // (it would not happen in this example, since reject is not called). }); Áp dụng cho lệnh gọi Ajax của chúng tôi, chúng tôi có thể sử dụng các lời hứa như thế này:


function ajax(url) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve(this.responseText);
    };
    xhr.onerror = reject;
    xhr.open('GET', url);
    xhr.send();
  });
}

ajax("/echo/json")
  .then(function(result) {
    // Code depending on result
  })
  .catch(function() {
    // An error occurred
  });

Mô tả tất cả các lợi thế mà lời hứa cung cấp nằm ngoài phạm vi của câu trả lời này, nhưng nếu bạn viết mã mới, bạn nên nghiêm túc xem xét chúng. Họ cung cấp một sự trừu tượng hóa và phân tách mã của bạn.

Thông tin thêm về lời hứa: Đá HTML5 - Lời hứa JavaScript

Lưu ý bên lề: Các đối tượng bị trì hoãn của jQuery Các đối tượng bị trì hoãn là việc thực hiện các lời hứa tùy chỉnh của jQuery (trước khi API Promise được chuẩn hóa). Họ hành xử gần giống như những lời hứa nhưng để lộ một API hơi khác.

Mọi phương thức Ajax của jQuery đã trả về một "đối tượng hoãn lại" (thực ra là một lời hứa về một đối tượng bị trì hoãn) mà bạn có thể trả về từ hàm của mình:


function ajax() {
    return $.ajax(...);
}

ajax().done(function(result) {
    // Code depending on result
}).fail(function() {
    // An error occurred
});
Lưu ý
``` phụ: Promise gotchas
Hãy nhớ rằng những lời hứa và các đối tượng bị trì hoãn chỉ là vật chứa cho một giá trị trong tương lai, bản thân chúng không phải là giá trị. Ví dụ: giả sử bạn có những điều sau đây:

function checkPassword() { return $.ajax({ url: '/password', data: { username: $('#username').val(), password: $('#password').val() }, type: 'POST', dataType: 'json' }); }

if (checkPassword()) { // Tell the user they're logged in }

Mã này hiểu sai các vấn đề không đồng bộ ở trên. Cụ thể, $.ajax()không đóng băng mã trong khi nó kiểm tra trang '/ password' trên máy chủ của bạn - nó sẽ gửi yêu cầu đến máy chủ và trong khi chờ, nó sẽ trả về ngay một đối tượng Trì hoãn Ajax, chứ không phải phản hồi từ máy chủ. Điều đó có nghĩa là ifcâu lệnh sẽ luôn lấy đối tượng Trì hoãn này, coi nó như truevà tiến hành như thể người dùng đã đăng nhập. Không tốt.

Nhưng cách khắc phục rất dễ:

checkPassword() .done(function(r) { if (r) { // Tell the user they're logged in } else { // Tell the user their password was bad } }) .fail(function(x) { // Tell the user something bad happened });

Không được đề xuất: Các cuộc gọi "Ajax" đồng bộ
Như tôi đã đề cập, một số hoạt động không đồng bộ (!) Có các đối tác đồng bộ. Tôi không ủng hộ việc sử dụng chúng, nhưng để hoàn thiện, đây là cách bạn sẽ thực hiện một cuộc gọi đồng bộ:

Không có jQuery
Nếu bạn trực tiếp sử dụng một XMLHTTPRequestđối tượng, chuyển falselàm đối số thứ ba cho .open.

jQuery
Nếu bạn sử dụng jQuery , bạn có thể đặt asynctùy chọn thành false. Lưu ý rằng tùy chọn này không được dùng kể từ jQuery 1.8. Sau đó, bạn vẫn có thể sử dụng một successcuộc gọi lại hoặc truy cập vào thuộc responseTexttính của đối tượng jqXHR :

function foo() { var jqXHR = $.ajax({ //... async: false }); return jqXHR.responseText; }

Nếu bạn sử dụng bất kỳ phương thức jQuery Ajax nào khác, chẳng hạn như $.get, $.getJSONv.v., bạn phải thay đổi nó thành $.ajax(vì bạn chỉ có thể truyền tham số cấu hình cho $.ajax).

Đứng lên! Không thể thực hiện một yêu cầu JSONP đồng bộ . JSONP về bản chất luôn luôn không đồng bộ (một lý do nữa để thậm chí không xem xét tùy chọn này).
admin posted 2/6/2020 6:24:59 AM

Nếu bạn không sử dụng jQuery trong mã của mình, câu trả lời này là dành cho bạn Mã của bạn phải là một cái gì đó dọc theo dòng này:


function foo() {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
    return httpRequest.responseText;
}

var result = foo(); // always ends up being 'undefined' Felix Kling đã làm rất tốt khi viết câu trả lời cho những người sử dụng jQuery cho AJAX, tôi đã quyết định cung cấp một giải pháp thay thế cho những người không biết.

( Lưu ý, đối với những người sử dụng fetchAPI mới , Angular hoặc lời hứa tôi đã thêm một câu trả lời khác bên dưới )

Những gì bạn đang đối mặt Đây là một bản tóm tắt ngắn gọn về "Giải thích vấn đề" từ câu trả lời khác, nếu bạn không chắc chắn sau khi đọc nó, hãy đọc nó.

Chữ A trong AJAX là viết tắt của không đồng bộ . Điều đó có nghĩa là gửi yêu cầu (hay đúng hơn là nhận phản hồi) được đưa ra khỏi luồng thực thi thông thường. Trong ví dụ của bạn, .sendtrả về ngay lập tức và câu lệnh tiếp theo return result;, được thực thi trước khi hàm bạn chuyển qua khi successgọi lại thậm chí được gọi.

Điều này có nghĩa là khi bạn quay lại, trình nghe bạn đã xác định chưa thực thi, điều đó có nghĩa là giá trị bạn trả về chưa được xác định.

Đây là một tương tự đơn giản

function getFive(){ var a; setTimeout(function(),10); return a; } (Vĩ cầm)

Giá trị atrả về là undefineddo a=5phần chưa được thực hiện. AJAX hoạt động như thế này, bạn đang trả lại giá trị trước khi máy chủ có cơ hội cho trình duyệt của bạn biết giá trị đó là gì.

Một giải pháp khả thi cho vấn đề này là mã hóa lại chủ động , cho chương trình của bạn biết phải làm gì khi tính toán hoàn tất.


function onComplete(a){ // When the code completes, do this
    alert(a);
}

function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);
}
Điều nà
```y được gọi là CPS . Về cơ bản, chúng tôi sẽ chuyển getFivemột hành động để thực hiện khi nó hoàn thành, chúng tôi sẽ nói cho mã của mình biết cách phản ứng khi sự kiện hoàn thành (như cuộc gọi AJAX của chúng tôi hoặc trong trường hợp này là hết thời gian chờ).

Cách sử dụng sẽ là:

getFive(onComplete);
Mà nên cảnh báo "5" cho màn hình. (Câu đố) .

Phương pháp khả thi
Về cơ bản có hai cách để giải quyết điều này:

Thực hiện cuộc gọi AJAX đồng bộ (hãy gọi nó là SJAX).
Cấu trúc lại mã của bạn để hoạt động đúng với các cuộc gọi lại.
1. AJAX đồng bộ - Đừng làm điều đó !!
Đối với AJAX đồng bộ, đừng làm điều đó! Câu trả lời của Felix nêu lên một số lập luận thuyết phục về lý do tại sao đó là một ý tưởng tồi. Tóm lại, nó sẽ đóng băng trình duyệt của người dùng cho đến khi máy chủ trả lời phản hồi và tạo ra trải nghiệm người dùng rất tệ. Đây là một bản tóm tắt ngắn khác được lấy từ MDN về lý do:

XMLHttpRequest hỗ trợ cả truyền thông đồng bộ và không đồng bộ. Tuy nhiên, nói chung, các yêu cầu không đồng bộ nên được ưu tiên hơn các yêu cầu đồng bộ vì lý do hiệu suất.

Nói tóm lại, các yêu cầu đồng bộ chặn việc thực thi mã ... ... điều này có thể gây ra sự cố nghiêm trọng ...

Nếu bạn phải làm điều đó, bạn có thể vượt qua một lá cờ: Đây là cách:

var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {// That's HTTP for 'ok'
  console.log(request.responseText);
}
2. Tái cấu trúc mã
Hãy để chức năng của bạn chấp nhận một cuộc gọi lại. Trong ví dụ mã foocó thể được thực hiện để chấp nhận một cuộc gọi lại. Chúng tôi sẽ nói cho mã của chúng tôi cách phản ứng khi foohoàn thành.

Vì thế:

var result = foo(); // code that depends on result goes here Trở thành:

foo(function(result) { // code that depends on result });

Ở đây chúng ta đã truyền một hàm ẩn danh, nhưng chúng ta có thể dễ dàng chuyển một tham chiếu đến một hàm hiện có, làm cho nó trông giống như:

function myHandler(result) {
    // code that depends on `result`
}
foo(myHandler);
Để biết thêm chi tiết về cách thiết kế gọi lại này được thực hiện, hãy kiểm tra câu trả lời của Felix.

Bây giờ, hãy xác định foo chính nó để hành động phù hợp

function foo(callback) { var httpRequest = new XMLHttpRequest(); httpRequest.onload = function(){ // when the request is loaded callback(httpRequest.responseText);// we're calling our method }; httpRequest.open('GET', "/echo/json"); httpRequest.send(); }

(vĩ cầm)

Bây giờ chúng ta đã làm cho hàm foo của chúng ta chấp nhận một hành động để chạy khi AJAX hoàn thành thành công, chúng ta có thể mở rộng điều này hơn nữa bằng cách kiểm tra xem trạng thái phản hồi không phải là 200 và hành động tương ứng (tạo một trình xử lý lỗi và như vậy). Giải quyết hiệu quả vấn đề của chúng tôi.

Nếu bạn vẫn gặp khó khăn trong việc này, hãy đọc hướng dẫn bắt đầu AJAX tại MDN.
admin posted 2/6/2020 6:25:41 AM

389

XMLHttpRequest 2 (trước hết hãy đọc câu trả lời từ Benjamin Gruenbaum & Felix Kling )

Nếu bạn không sử dụng jQuery và muốn có một XMLHttpRequest 2 ngắn đẹp, hoạt động trên các trình duyệt hiện đại và cả trên các trình duyệt di động, tôi khuyên bạn nên sử dụng nó theo cách này:

function ajax(a, b, c){ // URL, callback, just a placeholder c = new XMLHttpRequest; c.open('GET', a); c.onload = b; c.send() } Bạn có thể thấy:

Nó ngắn hơn tất cả các chức năng khác được liệt kê. Cuộc gọi lại được đặt trực tiếp (vì vậy không có thêm các lần đóng không cần thiết). Nó sử dụng tải mới (vì vậy bạn không phải kiểm tra trạng thái sẵn sàng &&) Có một số tình huống khác mà tôi không nhớ làm cho XMLHttpRequest 1 gây khó chịu. Có hai cách để nhận được phản hồi của lệnh gọi Ajax này (ba cách sử dụng tên var XMLHttpRequest):

Điều đơn giản nhất:

this.response Hoặc nếu vì lý do nào đó bạn bind()gọi lại cho một lớp:

e.target.response Thí dụ:

function callback(e){ console.log(this.response); } ajax('URL', callback); Hoặc (một trong những chức năng ẩn danh tốt hơn luôn là một vấn đề):

ajax('URL', function(e){console.log(this.response)}); Không có gì dễ dàng hơn.

Bây giờ một số người có thể sẽ nói rằng tốt hơn là sử dụng onreadystatechange hoặc thậm chí tên biến XMLHttpRequest. Sai rồi.

Kiểm tra các tính năng nâng cao của XMLHttpRequest

Nó hỗ trợ tất cả * trình duyệt hiện đại. Và tôi có thể xác nhận rằng tôi đang sử dụng phương pháp này kể từ khi XMLHttpRequest 2 tồn tại. Tôi chưa bao giờ có bất kỳ loại vấn đề nào trên tất cả các trình duyệt tôi sử dụng.

onreadystatechange chỉ hữu ích nếu bạn muốn có được các tiêu đề ở trạng thái 2.

Sử dụng XMLHttpRequesttên biến là một lỗi lớn khác khi bạn cần thực hiện cuộc gọi lại bên trong việc đóng onload / oreadystatechange nếu không bạn đã mất nó.

Bây giờ nếu bạn muốn một cái gì đó phức tạp hơn bằng cách sử dụng bài đăng và FormData, bạn có thể dễ dàng mở rộng chức năng này:

function x(a, b, e, d, c){ // URL, callback, method, formdata or ,placeholder c = new XMLHttpRequest; c.open(e||'get', a); c.onload = b; c.send(d||null) } Một lần nữa ... đó là một chức năng rất ngắn, nhưng nó có được & đăng.

Ví dụ về việc sử dụng:

x(url, callback); // By default it's get so no need to set x(url, callback, 'post', {'key': 'val'}); // No need to set post data Hoặc vượt qua một phần tử dạng đầy đủ ( document.getElementsByTagName('form')[0]):

var fd = new FormData(form); x(url, callback, 'post', fd); Hoặc đặt một số giá trị tùy chỉnh:

var fd = new FormData(); fd.append('key', 'val') x(url, callback, 'post', fd); Như bạn có thể thấy tôi đã không thực hiện đồng bộ hóa ... đó là một điều tồi tệ.

Đã nói rằng ... tại sao không làm điều đó một cách dễ dàng?

Như đã đề cập trong bình luận, việc sử dụng lỗi && đồng bộ hoàn toàn phá vỡ điểm của câu trả lời. Đó là một cách ngắn hay để sử dụng Ajax theo cách thích hợp?

Xử lý lỗi


function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val}, placeholder
  c = new XMLHttpRequest;
  c.open(e||'get', a);
  c.onload = b;
  c.onerror = error;
  c.send(d||null)
}

function error(e){
  console.log('--Error--', this.type);
  console.log('this: ', this);
  console.log('Event: ', e)
}
function displayAjax(e){
  console.log(e, this);
}
x('WRONGURL', displayAjax);

Trong đoạn script trên, bạn có một trình xử lý lỗi được xác định tĩnh để nó không ảnh hưởng đến hàm. Trình xử lý lỗi cũng có thể được sử dụng cho các chức năng khác.

Nhưng để thực sự nhận ra một lỗi, cách duy nhất là viết một URL sai trong trường hợp mọi trình duyệt đều đưa ra một lỗi.

Trình xử lý lỗi có thể hữu ích nếu bạn đặt tiêu đề tùy chỉnh, đặt answerType thành bộ đệm mảng blob hoặc bất cứ điều gì ...

Ngay cả khi bạn vượt qua 'POSTAPAPAP' như phương thức, nó sẽ không gây ra lỗi.

Ngay cả khi bạn vượt qua 'fdggdgilfdghfldj' dưới dạng formdata, nó sẽ không gây ra lỗi.

Trong trường hợp đầu tiên lỗi là bên trong displayAjax()dưới this.statusTextnhư Method not Allowed.

Trong trường hợp thứ hai, nó chỉ đơn giản hoạt động. Bạn phải kiểm tra ở phía máy chủ nếu bạn chuyển đúng dữ liệu bài đăng.

tên miền chéo không được phép ném lỗi tự động.

Trong phản hồi lỗi, không có mã lỗi.

Chỉ có this.typecái được đặt thành lỗi.

Tại sao thêm một trình xử lý lỗi nếu bạn hoàn toàn không kiểm soát được lỗi? Hầu hết các lỗi được trả lại bên trong này trong chức năng gọi lại displayAjax().

Vì vậy: Không cần kiểm tra lỗi nếu bạn có thể sao chép và dán URL đúng cách. 😉

PS: Là thử nghiệm đầu tiên tôi đã viết x ('x', displayAjax) ..., và nó hoàn toàn có phản hồi ... ??? Vì vậy, tôi đã kiểm tra thư mục chứa HTML và có một tệp có tên 'x.xml'. Vì vậy, ngay cả khi bạn quên phần mở rộng của tệp XMLHttpRequest 2 SILL TÌM NÓ . Tôi LOL

Đọc một tập tin đồng bộ

Đừng làm vậy.

Nếu bạn muốn chặn trình duyệt trong một thời gian, hãy tải một .txttệp lớn đồng bộ đẹp.

function omg(a, c){ // URL c = new XMLHttpRequest; c.open('GET', a, true); c.send(); return c; // Or c.response } Bây giờ bạn có thể làm

var res = omg('thisIsGonnaBlockThePage.txt'); Không có cách nào khác để làm điều này theo cách không đồng bộ. (Vâng, với vòng lặp setTimeout ... nhưng nghiêm túc chứ?)

Một điểm khác là ... nếu bạn làm việc với API hoặc chỉ các tệp trong danh sách của riêng bạn hoặc bất cứ điều gì bạn luôn sử dụng các chức năng khác nhau cho mỗi yêu cầu ...

Chỉ khi bạn có một trang nơi bạn tải luôn cùng một XML / JSON hoặc bất cứ thứ gì bạn chỉ cần một hàm. Trong trường hợp đó, hãy sửa đổi một chút hàm Ajax và thay thế b bằng hàm đặc biệt của bạn.

Các chức năng trên là để sử dụng cơ bản.

Nếu bạn muốn loại bỏ chức năng ...

Vâng, bạn có thể.

Tôi đang sử dụng rất nhiều API và một trong những hàm đầu tiên tôi tích hợp vào mọi trang HTML là hàm Ajax đầu tiên trong câu trả lời này, chỉ với GET ...

Nhưng bạn có thể làm rất nhiều thứ với XMLHttpRequest 2:

Tôi đã tạo một trình quản lý tải xuống (sử dụng các phạm vi ở cả hai phía với sơ yếu lý lịch, trình quay phim, hệ thống tập tin), các trình chuyển đổi hình ảnh khác nhau bằng cách sử dụng canvas, điền vào cơ sở dữ liệu SQL web với các cơ sở 64 và nhiều hơn nữa ... Nhưng trong những trường hợp này, bạn chỉ nên tạo một hàm cho điều đó mục đích ... đôi khi bạn cần một blob, bộ đệm mảng, bạn có thể đặt tiêu đề, ghi đè mimetype và có nhiều hơn nữa ...

Nhưng câu hỏi ở đây là làm thế nào để trả về phản hồi Ajax ... (Tôi đã thêm một cách dễ dàng.)

Có câu trả lời không? Đăng nhập hoặc là Đăng ký để gửi câu trả lời của bạn
câu trả lời của bạn
Hủy bỏ
Chi tiết
  • Đăng 2/6/2020 6:21:56 AM
  • 1 lượt xem, 0 replies