我正在使用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
但我正在寻找的确切事项是
我如何将请求与一般回应联系起来?
这是我如何决定哪个响应属于哪个请求(我是否过度假设?)
答案 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
所做的那样。