构建一堆JSONP请求

时间:2011-07-31 21:12:16

标签: javascript dom jsonp

我正在使用wikipedia api和构建一个自动建议框,问题是DOM的更新顺序是基于从服务器检索到的响应顺序,而它实际上应该依赖于顺序发射onkeyup事件。 所以如果我正在寻找Lady Gaga,我按L然后按a。如果来自我正在寻找L的请求的响应晚于La的响应1}}然后DOM更新了L的响应,这不应该发生,因为我最近的输入是La

因此,在每个onkeyup事件中创建一个Request对象,该对象具有创建请求时的时间戳(onkeyup事件被触发)并将其存储为全局数组{{1} }。还有全局变量requests,它存储实际修改lastValidRequest的最后一个Request对象的时间戳。在回调函数中,我检查其时间戳小于DOM的{​​{1}}是否丢弃这些请求,因为它们比已发送的更新Request。我已尽最大努力评估代码,使每件事都易于理解。代码看起来像这样

lastValidRequest

此代码here

Request个链接

更新

我已经想出了如何摆脱<script type="text/javascript"> var requests=new Array(); // array to hold requests var lastValidRequest=(new Date()).getTime(); // shows the time of the last request whose callback function was called function cb(data) // calls send method of Request object { requests[requests.length-1].send(data); //this is where i m going wrong but i dont know wat to do here } function Request(url) //request constructor { this.time=(new Date()).getTime(); //time at which request was created this.url=url+"&callback=cb"; this.node=document.createElement('script'); this.node.src=this.url; this.ran=false; // indicates whether this request modified the div element's contents,just used for making debuuging easy return this; }; Request.prototype.send=function(data) { if (this.time < lastValidRequest) // check if a newer request has been made { this.node.parentNode.removeChild(this.node); // cancel the request //this.node=null; } else // this is the newest request { lastValidRequest=this.time; //set lastValidRequest to time of this request this.ran=true; var str=""; for(var i=0;i<data[1].length;i++) str=str+data[1][i]+"</br>"; document.getElementById('content').innerHTML=str; this.node.parentNode.removeChild(this.node); } }; window.onload=function() { textbox=document.getElementById('search'); textbox.onkeyup=function() { var text=textbox.value; // text is the query for the GET request if(text=="") { document.getElementById('content').innerHTML=""; return; } var url="http://en.wikipedia.org/w/api.php?action=opensearch&search=" +text + "&limit=10&namespace=0&format=json"; requests.push(new Request(url)); // create a new request and add it to the end of the array document.body.appendChild(requests[requests.length-1].node); } } </script> ,因为当它返回搜索响应时,它也会返回搜索查询。例如,如果我搜索pastebin,则返回的wikipedia api响应是

gaga

现在我可以很容易地找出哪个响应属于哪个请求。所以我可以做这样的事情来看看响应是否适用于最近的请求

JSON

但我正在寻找的确切事项是

我如何将请求与一般回应联系起来?

这是我如何决定哪个响应属于哪个请求(我是否过度假设?

1 个答案:

答案 0 :(得分:3)

您需要做的是通过中止前一个连接一次只允许一个连接。

不幸的是,我不太了解你的代码,看看它是如何完成的,但是使用常规的AJAX和jQuery,它看起来像:

<script type="text/javascript">
    $(document).ready(function(){

        var curr_request=null;

        $('#autosuggest').keyup(function(){

            // abort existing request
            if(curr_request)curr_request.abort();

            // do the request
            curr_request = $.getJSON(the_url,function(data){
                curr_request=null;
                // populate autosuggest with data
            });

        });
    });
</script>

编辑:由于您正在处理JSONP,要“中止”请求,您可能必须从文档中删除脚本节点。像document.body.removeChild(requests[requests.length-1].node);之类的东西 如果是这样,你也不需要保留堆栈,只需跟踪最后一个堆栈,就像我在我的示例中使用curr_request所做的那样。