简体   繁体   English

如何缓冲 Ajax 请求?

[英]How to buffering an Ajax Request?

I have a simple Ajax function, something like this:我有一个简单的 Ajax 函数,如下所示:

var x;
var myRequest = new Array();

function CreateXmlHttpReq(handler) {
    var xmlhttp = null;
    try {
        xmlhttp = new XMLHttpRequest();
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    xmlhttp.onreadystatechange = handler;
    return xmlhttp;
}

function getResults() {
    var r = Math.random();
    var someVar = document.getElementById("myvar").value;
    var myUrl = "url/of/my/phpScript.php?";
    myUrl += "r=" + r;
    //encodeURIComponent() instead of escape() when i aspect normal text
    myUrl += "&someVar=" + escape(someVar);
    //startLoading just show an overlay with a small rotating gif
    startLoading();
    x++;
    myRequest[x] = CreateXmlHttpReq(function () {
        printResultHandler(x);
    });
    myRequest[x].open("GET", myUrl);
    myRequest[x].send(null);
}

//example handler
function printResultHandler(x) {
    if (myRequest[x].readyState == 4 && myRequest[x].status == 200) {
        //usually i use innerHTML for quick requests, the DOM for more complex req
        document.getElementById(div).innerHTML = myRequest[x].responseText;
        //this will hide the overlay showed ith startLoading()
        stopLoading();
    }
}

and that works fine.这工作正常。 I just have some problems when the return flux is big (it can be XML, HTML, or whatever), the browser seems to 'fall asleep' for a while.我只是在返回流量很大(可以是 XML、HTML 或其他任何内容)时遇到一些问题,浏览器似乎会“睡着”一段时间。 I don't like to have a big amount of text (XML, HTML) all in one.我不喜欢将大量文本(XML、HTML)合二为一。 It isn't nice to handle that.处理这个不好。

I'm wondering if there exists some way to buffer that request.我想知道是否存在某种方法来缓冲该请求。 When the request is done and returns the 200 status, is there a way to get the responseText piece by piece (let's say 2048 bytes or line by line)?当请求完成并返回200状态时,有没有办法逐个获取 responseText(假设为 2048 字节或逐行)? I suppose something like:我想是这样的:

function printResultHandler(x) {
    if (myRequest[x].readyState == 4 && myRequest[x].status == 200) {
        //usually i use innerHTML for quick requests, the DOM for more complex req
        //document.getElementById(div).innerHTML = myRequest[x].responseText;
        var answer;
        while ((answer = readline(myRequest[x].responseText))) {
            //to something;
        }
        //this will hide the overlay showed ith startLoading()
        stopLoading();
    }
}

In short, the equivalent of the readdir() or fread() of PHP.简而言之,相当于 PHP 的readdir()fread()

Agreed, buffering a request is not really something you can do.同意,缓冲请求并不是您真正可以做的事情。

You can consider staggering a user request for data over a set of HTTP requests, parsing and processing each HTTP request as it comes back.您可以考虑通过一组 HTTP 请求错开用户对数据的请求,在每个 HTTP 请求返回时对其进行解析和处理。

For example, if the user wishes to request records 1 to 1000, the client could first request records 1 to 100, process, parse and render that, then request records 101 to 200 and so on.例如,如果用户希望请求记录 1 到 1000,客户端可以首先请求记录 1 到 100,处理、解析和呈现它,然后请求记录 101 到 200,依此类推。 The first 100 records would display relatively quickly and, after a short period, the next 100 records would display.前 100 条记录会相对较快地显示出来,过一小段时间后,接下来的 100 条记录就会显示出来。 So long as the second 100 records displays before the user has managed to deal with the first 100 records it should be ok.只要在用户设法处理前 100 条记录之前显示后 100 条记录,就应该没问题。 The overall time to complete the request will be longer, however the web app will appear more responsive and the perceived task completion time will be lower.完成请求的总时间会更长,但 Web 应用程序的响应速度会更快,感知的任务完成时间会更短。

You should also consider switching from XML to JSON if you're not just updating the innerHTML property of an element with data.如果您不只是用数据更新元素的 innerHTML 属性,您还应该考虑从 XML 切换到 JSON。

To display to the user the response to an AJAX request, the response must first be parsed into a data structure and then rendered.要向用户显示对 AJAX 请求的响应,必须首先将响应解析为数据结构,然后呈现。 Surprisingly, the parse time for both XML and JSON is pretty much the same.令人惊讶的是,XML 和 JSON 的解析时间几乎相同。 The difference lies in the time required to traverse and read the resulting data structure.不同之处在于遍历和读取结果数据结构所需的时间。

Browser functions for traversing and accessing the data within the DOM of a parsed response are relatively slow.用于遍历和访问已解析响应的 DOM 内数据的浏览器函数相对较慢。 Browser DOM API methods mask the complexity of what is involved in DOM traversing and make a slow process look nice and simple.浏览器 DOM API 方法掩盖了 DOM 遍历所涉及的复杂性,并使缓慢的过程看起来既美观又简单。

Accessing data in JavaScript objects resulting from the parsing of a JSON-formatted response is much quicker.通过解析 JSON 格式的响应来访问 JavaScript 对象中的数据要快得多。 Traversing a JavaScript object is easily 2 to 3 times faster than traversing a DOM tree for the same set of data.对于相同的数据集,遍历 JavaScript 对象比遍历 DOM 树快 2 到 3 倍。

In recent tests I carried out with FireFox 3.1 beta 2 using 10Mb of source data, traversing the DOM of an XML response took about 30 seconds.在最近的测试中,我使用 10Mb 的源数据对 FireFox 3.1 beta 2 进行了测试,遍历 XML 响应的 DOM 需要大约 30 秒。 Doing the same for a JavaScript object populated from the same original large data set took about 15 seconds.对从相同的原始大数据集填充的 JavaScript 对象执行相同操作大约需要 15 秒。

No, there is no way to buffer the request.不,没有办法缓冲请求。 If you return a huge amount of data and then try to insert it into the page all at once it is always going to take a long time for all that to be parsed.如果您返回大量数据,然后尝试将其一次性全部插入页面,则解析所有数据总是需要很长时间。

You might want to consider if there is another way to get the results you want.. Is there is reason you have to insert such a large amount of data into the page with an AJAX request?您可能要考虑是否有另一种方法来获得您想要的结果.. 是否有理由必须使用 AJAX 请求将如此大量的数据插入到页面中?

You have to do it manually (aka code it for yourself).您必须手动完成(也就是为自己编写代码)。

An easy solution is the following (C=client, S=server)一个简单的解决方案如下(C=client,S=server)

  • C send the request C 发送请求
  • S prepare the whole output S 准备整个输出
  • S generates some kind of data identifier key (md5 of the data for example) S 生成某种数据标识符密钥(例如数据的 md5)
  • S cuts th data into chunks and saves them (and determine the chunk count) S 将数据切成块并保存(并确定块数)
  • S returns the data identifier (and maybe the chunk count) S 返回数据标识符(可能还有块数)
  • C iterates from the first chunk to the last, sends the server the data key (and the chunk number) C 从第一个块迭代到最后一个,将数据键(和块号)发送给服务器
  • S returns the requested chunk S 返回请求的块
  • C displays the chunk (or a content is loading progress bar) C 显示块(或一个内容正在加载进度条)

The caveat is that if you don't go on the progress bar way but instead the instand processing, then S have to cut the data into chunks as partially correct pieces of code what is processable by C.需要注意的是,如果您不采用进度条方式而是进行即时处理,那么 S 必须将数据切成块作为部分正确的代码片段,C 可以处理这些代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM