我有一个Ajax调用更新数据库中的5,000条记录,因此这需要很多时间。我有一个Ajax“加载图像”显示发生了一些事情,但我正在寻找一个更好的方式来显示“更新50的5000。。”,“更新200的5000”或类似的东西。
什么是最好的方式来做这样的事情在Ajax / jQuery没有做5000个不同的帖子?
解决方法
最好的我认为是使用
Comet。
在Comet风格的应用程序中,服务器本质上可以将数据推送到客户端(而不是一次又一次地从服务器请求数据)。客户端只需要连接到服务器一次。然后服务器将继续将数据推回客户端。
维基百科:
Comet is a programming technique that enables web servers to send data to the client without having any need for the client to request it. It allows creation of event-driven web applications which are hosted in the browser.
现在让我们看看彗星如何工作。请参阅以下服务器端代码。这里使用一个while循环,你可以改为设置自己的条件。在while循环中,页面写入一个datetime并刷新,然后休眠1/2秒。
public static string Delimiter = "|"; protected void Page_Load(object sender,EventArgs e) { Response.Buffer = false; while (true) { Response.Write(Delimiter + DateTime.Now.ToString("HH:mm:ss.FFF")); Response.Flush(); // Suspend the thread for 1/2 a second System.Threading.Thread.Sleep(500); } // Yes I know we'll never get here,// it's just hard not to include it! Response.End(); }
客户端代码 – 纯JavaScript
只做一次请求,然后继续检查XMLHttpRequest的readyState === 3中的数据。
function getData() { loadXMLDoc("Service.aspx"); } var req = false; function createRequest() { req = new XMLHttpRequest(); // http://msdn.microsoft.com/en-us/library/ms535874%28v=vs.85%29.aspx } function loadXMLDoc(url) { try { if (req) { req.abort(); req = false; } createRequest(); if (req) { req.onreadystatechange = processReqChange; req.open("GET",url,true); req.send(""); } else { alert('unable to create request'); } } catch (e) { alert(e.message); } } function processReqChange() { if (req.readyState == 3) { try { ProcessInput(req.responseText); // At some (artibrary) length recycle the connection if (req.responseText.length > 3000) { lastDelimiterPosition = -1; getData(); } } catch (e) { alert(e.message); } } } var lastDelimiterPosition = -1; function ProcessInput(input) { // Make a copy of the input var text = input; // Search for the last instance of the delimiter var nextDelimiter = text.indexOf('|',lastDelimiterPosition + 1); if (nextDelimiter != -1) { // Pull out the latest message var timeStamp = text.substring(nextDelimiter + 1); if (timeStamp.length > 0) { lastDelimiterPosition = nextDelimiter; document.getElementById('outputZone').innerHTML = timeStamp; } } } window.onload = function () { getData(); };