2010-09-21 29 views
10

Có cách nào trong JavaScript để gửi yêu cầu HTTP đến máy chủ HTTP và đợi cho đến khi máy chủ phản hồi bằng câu trả lời không? Tôi muốn chương trình của tôi đợi cho đến khi máy chủ trả lời và không thực hiện bất kỳ lệnh nào khác sau yêu cầu này. Nếu máy chủ HTTP bị hỏng, tôi muốn yêu cầu HTTP được lặp lại sau một thời gian chờ cho đến khi máy chủ trả lời, và sau đó việc thực hiện chương trình có thể tiếp tục bình thường.Làm cách nào để buộc chương trình đợi cho đến khi yêu cầu HTTP được hoàn thành trong JavaScript?

Bất kỳ ý tưởng nào?

Cảm ơn bạn trước, Thanasis

+6

Tôi thực sự muốn mọi người sẽ để lại ý kiến ​​giải thích khi họ -1. – kojiro

Trả lời

10

Bạn có thể thực hiện một yêu cầu đồng bộ. Ví dụ jQuery:

$(function() { 
    $.ajax({ 
     async: false, 
     // other parameters 
    }); 
}); 

Bạn nên xem jQuery AJAX API. Tôi khuyên bạn nên sử dụng một khung công tác như jQuery cho công cụ này. Làm thủ công ajax qua trình duyệt là một nỗi đau thực sự!

+0

đây là cách tốt nhất! Tuy nhiên, nhiều người nghĩ rằng JS Frameworks là ác và có xu hướng mã hóa tất cả mọi thứ mình. – Alex

+0

Tôi đã cố gắng làm điều đó với nhiều cách sử dụng XmlHttpRequest ví dụ, nhưng tôi đã không tìm thấy một cách để dừng việc thực hiện cho đến khi tôi nhận được một phản ứng .. –

+4

Alex, đó là tôi! Tôi là một trông số chúng! ;) –

0

Đối với điều này, bạn có thể bắt đầu tải trong javascript ngay sau khi trang bắt đầu tải và sau đó bạn có thể đóng nó khi yêu cầu hoàn tất hoặc dom của bạn đã sẵn sàng. Điều tôi đang cố gắng nói, khi tải trang bắt đầu, hãy bắt đầu trình tải. Sau đó, trang có thể thực hiện nhiều yêu cầu đồng bộ bằng ajax, cho đến khi và trừ khi bạn không nhận được phản hồi, đừng đóng trình tải gần. Sau khi nhận được phản hồi mong muốn trong cuộc gọi cuối cùng, bạn có thể đóng bộ nạp.

+1

bạn đang tắt ... hỏi về việc trì hoãn nhiều yêu cầu. – Alex

+0

Vâng, đó là chính xác những gì tôi muốn làm .. –

+0

@Thanasis Petsas: Vui lòng kiểm tra bài đăng đã chỉnh sửa. Hy vọng điều này có thể giúp bạn. – Nik

2

Bạn có thể sử dụng đối tượng XMLHttpRequest để gửi yêu cầu của mình. một khi bạn gửi yêu cầu của bạn, bạn có thể readyState tài sản để xác định nhà nước. readyState sẽ có các trạng thái khác nhau sau.

  • uninitialized - Chưa bắt đầu tải chưa
  • tải - Được tải
  • tương tác - đã nạp đủ và người dùng có thể tương tác với nó
  • hoàn chỉnh - nạp đầy đủ

ví dụ:

xmlhttp.open("GET","somepage.xml",true); 
xmlhttp.onreadystatechange = checkData; 
xmlhttp.send(null); 

function checkData() 
{ 
    alert(xmlhttp.readyState); 
} 

hy vọng điều này sẽ giúp

+0

Tôi muốn thực hiện chương trình được nối tiếp và tôi không muốn sử dụng gọi lại. Tôi muốn nếu có thể dừng việc thực hiện chương trình tại "xmlhttp.send (null);" gọi và sau đó tiếp tục sau khi yêu cầu kết thúc. –

+0

Bạn có thể chơi với tài sản readyState. Có thể là bạn có thể đặt nó trong khi vòng lặp và do đó nó sẽ không đi đến dòng tiếp theo cho đến khi thực hiện xong. Ngoài ra nếu bạn có thể dự đoán thời gian thực hiện, bạn có thể sử dụng hàm setTimeOut(). thêm về chức năng này bạn có thể đọc ở đây. http://www.w3schools.com/jsref/met_win_settimeout.asp – Akie

0

Tôi có tình huống tương tự trong trò chơi được xây dựng với Three.js và Google Closure. Tôi phải tải 2 tài nguyên, ba và đóng cửa không cho phép tôi thực hiện những đồng bộ này.

Ban đầu tôi ngây thơ đã viết như sau:

main() { 

    ... 
    var loaded=0; 
    ... 

    // Load Three geometry 
    var loader = new THREE.JSONLoader(); 
    loader.load("x/data.three.json", function(geometry) { 
    ... 
    loaded++; 
    }); 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 
    loaded++; 
    }); 

    // Wait for callbacks to complete 
    while(loaded<2) {} 

    // Initiate an animation loop 
    ... 
}; 

Các vòng lặp mà chờ đợi cho callbacks để hoàn thành không bao giờ kết thúc, từ quan điểm của vòng lặp loaded không bao giờ có được tăng lên. Vấn đề là các cuộc gọi lại không được kích hoạt cho đến khi main trả về (ít nhất là trên Chrome).

Một giải pháp có thể là có cả hai cuộc gọi lại kiểm tra xem đó có phải là lần cuối cùng hoàn thành và họ tiếp tục bắt đầu vòng lặp hoạt ảnh hay không.

Một giải pháp - có lẽ là một câu trả lời trực tiếp hơn với những gì bạn đang yêu cầu (làm thế nào để chờ đợi cho mỗi tải trước khi bắt đầu khác) - sẽ được tổ callbacks như sau:

// Load Three geometry 
var loader = new THREE.JSONLoader(); 
loader.load("x/data.three.json", function(geometry) { 
    ... 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 

    // Initiate an animation loop 
    ... 

    }); 
    }); 
}; 
+1

Xin chào Argenti, chào mừng bạn đến với stackoverflow! Hãy làm cho câu trả lời của bạn càng rõ ràng càng tốt. Sử dụng dấu ngoặc nhọn hoặc quấn mã của bạn bằng ký tự \ '. Nếu có thể, hãy thử và xem bạn có thể có được thứ gì đó để chạy trước khi đăng bài hay không. Những câu hỏi này cũng có thể được đề cập trong tương lai, vì vậy hãy cố gắng và nỗ lực! –

+0

Tôi tìm thấy điều này: Lưu ý: _Bắt đầu với Gecko 30.0 (Firefox 30.0/Thunderbird 30.0/SeaMonkey 2.27), yêu cầu đồng bộ trên chủ đề chính đã không được chấp nhận do tác động tiêu cực đến trải nghiệm người dùng._ [Mozilla Dev.Network] (https : //developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) –

18

Có một tham số thứ ba đến XmlHttpRequest :: open(), nhằm mục đích chỉ ra rằng bạn muốn yêu cầu đến bởi không đồng bộ (và do đó xử lý các phản ứng thông qua một bộ xử lý onreadystate).

Vì vậy, nếu bạn muốn nó được đồng bộ (tức là chờ câu trả lời), chỉ cần chỉ định sai cho đối số thứ ba này. Bạn cũng có thể muốn đặt thuộc tính thời gian chờ giới hạn cho yêu cầu của mình trong trường hợp này, vì nó sẽ chặn trang cho đến khi tiếp nhận.

Dưới đây là một chức năng mẫu all-in-one cho cả đồng bộ và async:

function httpRequest(address, reqType, asyncProc) { 
    var r = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); 
    if (asyncProc) 
     r.onreadystatechange = function() { 
      if (this.readyState == 4) asyncProc(this); 
     }; 
    else 
     r.timeout = 4000; // Reduce default 2mn-like timeout to 4 s if synchronous 
    r.open(reqType, address, !(!asyncProc)); 
    r.send(); 
    return r; 
} 

mà bạn có thể gọi theo cách này:

var req = httpRequest("http://example.com/aPageToTestForExistence.html", "HEAD"); // In this example you don't want to GET the full page contents 
alert(req.status == 200 ? "found!" : "failed"); // We didn't provided an async proc so this will be executed after request completion only 
+0

Điều này dẫn tôi đến thư viện không đồng bộ, điều này làm cho việc này cực kỳ đơn giản. https://github.com/caolan/async/ Đừng để bị lừa bởi chuyến tàu đóng gói. Bạn chỉ cần bao gồm một tệp javascript nhỏ - async.js! – tudor

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