2009-12-18 30 views
8

Tôi đang tìm cách thiết lập trang web lấy mẫu dữ liệu qua các cuộc gọi AJAX từ máy chủ web nhúng. Làm cách nào để tôi thiết lập mã để một yêu cầu không trùng lặp với một yêu cầu khác? Tôi nên đề cập đến tôi có rất ít kinh nghiệm JavaScript và cũng là một lý do thuyết phục không sử dụng các thư viện bên ngoài có kích thước lớn hơn 10 hoặc nhiều kilobyte.Làm cách nào để thực hiện cuộc gọi Ajax trong khoảng thời gian mà không bị trùng lặp?

+6

Chào mừng bạn đến với StackOverflow. Câu hỏi đầu tiên tuyệt vời. – Sampson

Trả lời

1

AJAX, mặc dù tên, không cần phải không đồng bộ.

Dưới đây là phương pháp không đồng bộ ...

var req; 

function ajax(method,url,payload,action) 
    { 
    if (window.XMLHttpRequest) 
     { 
     req = new XMLHttpRequest(); 
     req.onreadystatechange = action; 
     req.open(method, url, true); 
     req.send(payload); 
     } 
    else if (window.ActiveXObject) 
     { 
     req = new ActiveXObject("Microsoft.XMLHTTP"); 
     if (req) 
      { 
      req.onreadystatechange = action; 
      req.open(method, url, true); 
      req.send(payload); 
      } 
     else 
      { 
      alert("Could not create ActiveXObject(Microsoft.XMLHTTP)"); 
      } 
     } 
    } 

... nhưng đây là một tương đương đồng bộ ...

function sjax(method,url,payload,action) 
    { 
    if (window.XMLHttpRequest) 
     { 
     req = new XMLHttpRequest(); 
     req.open(method, url, false); 
     req.send(payload); 
     action(); 
     } 
    else if (window.ActiveXObject) 
     { 
     req = new ActiveXObject("Microsoft.XMLHTTP"); 
     if (req) 
      { 
      req.onreadystatechange = action; 
      req.open(method, url, false); 
      req.send(payload); 
      } 
     else 
      { 
      alert("Could not create ActiveXObject(Microsoft.XMLHTTP)"); 
      } 
     } 
    } 

... và đây là một hành động điển hình ...

function insertHtml(target) 
    { 
    var pageTarget = arguments[0]; 
    if (req.readyState == 4) // 4 == "loaded" 
     { 
     if (req.status == 200) // 200 == "Ok" 
      { 
      if (req.responseText.indexOf("error") >= 0) 
       { 
       alert("Please report the following error..."); 
       pretty = req.responseText.substring(req.responseText.indexOf("error"),1200); 
       pretty = pretty.substring(0,pretty.indexOf("\"")); 
       alert(pretty + "\n\n" + req.responseText.substring(0,1200)); 
       } 
      else 
       { 
       div = document.getElementById(pageTarget); 
       div.innerHTML = req.responseText; 
       dimOff(); 
       } 
      } 
     else 
      { 
      alert("Could not retreive URL:\n" + req.statusText); 
      } 
     } 
    } 
+0

yêu cầu đồng bộ không thực sự là ý tưởng tốt nhất, theo ý kiến ​​của tôi, chúng cũng khóa phần còn lại của trang .... nhưng điều này phụ thuộc vào yêu cầu của người dùng. cũng từ tài liệu jQuery $ .ajax: "Tốt hơn nên chặn tương tác người dùng bằng các phương tiện khác khi cần đồng bộ hóa". –

0

Tôi đề nghị bạn sử dụng bộ công cụ nhỏ như jx.js (source). Bạn có thể tìm thấy nó ở đây: http://www.openjs.com/scripts/jx/ (ít hơn 1k minified)

Để thiết lập một yêu cầu:

jx.load('somepage.php', function(data){ 
    alert(data); // Do what you want with the 'data' variable. 
}); 

Để cài đặt nó trên một khoảng thời gian bạn có thể sử dụng setInterval và một biến để lưu trữ hay không một yêu cầu hiện đang xảy ra - nếu nó là, chúng tôi đơn giản không làm gì cả:

var activeRequest = false; 
setInterval(function(){ 

    if (!activeRequest) { 
     // Only runs if no request is currently occuring: 
     jx.load('somepage.php', function(data){ 
      activeRequest = false; 
      alert(data); // Do what you want with the 'data' variable. 
     }); 
    } 
    activeRequest = true; 

}, 5000); // Every five seconds 
+0

Giống như câu trả lời khác ... Vậy tại sao lại lãng phí khoảng thời gian, thay vì chỉ thực hiện các cuộc gọi đồng bộ. Bạn sẽ có chất thải trung bình 5000ms/2 bằng cách bỏ phiếu. – dacracot

6

bạn có thể muốn xem xét các tùy chọn của việc tái giới thiệu yêu cầu AJAX của bạn chỉ sau một phản ứng thành công từ các cuộc gọi AJAX trước.

function autoUpdate() 
{ 
    var ajaxConnection = new Ext.data.Connection(); 

    ajaxConnection.request(
    { 
     method:   'GET', 
     url:   '/web-service/', 

     success: function(response) 
     { 
      // Add your logic here for a successful AJAX response. 
      // ... 
      // ... 

      // Relaunch the autoUpdate() function in 5 seconds. 
      setTimeout(autoUpdate, 5000); 
     } 
    } 
} 

Ví dụ này sử ExtJS, nhưng bạn có thể rất dễ dàng sử dụng chỉ XMLHttpRequest.

LƯU Ý: Nếu bạn phải có một khoảng thời gian chính xác của x giây, bạn sẽ phải theo dõi thời gian trôi qua từ khi yêu cầu AJAX đã được đưa ra cho đến setTimeout() cuộc gọi, và sau đó trừ đi khoảng thời gian này từ sự trì hoãn. Nếu không, khoảng thời gian trong ví dụ trên sẽ thay đổi theo thời gian chờ của mạng và với thời gian xử lý logic dịch vụ web.

+0

không chính xác những gì họ đã yêu cầu, nhưng một giải pháp rất tốt (chỉ để sử dụng callbacks) –

+1

Câu trả lời hay. Tuy nhiên bạn có thể muốn 'setTimeout' sau khi các cuộc gọi Ajax trước đó được thực hiện, bất kể nó có thành công hay không. Nếu không, lần đầu tiên bạn có thời gian chờ hoặc lỗi, bạn sẽ ngừng nhận cập nhật. – Grodriguez

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