Я создаю окно автоматической подсказки с API-интерфейсом Wikipedia и . Проблема в том, что порядок обновлений DOM
основан на порядке ответов, полученных с сервера, тогда как на самом деле он должен зависеть от порядка запуска.onkeyup
событие. , так что если я ищу Lady Gaga
, и я нажимаю L
, а затем a
.now, если ответ на запрос, где я ищу L
, приходит позже, чем ответ для La
затем DOM
обновляется ответом L, что не должно произойти, потому что мой самый последний ввод - La
.
Поэтому при каждом событии onkeyup
создается объект Request
, который имеет метку временикогда запрос был создан (onkeyup
событие сработало) и сохранить его в глобальном массиве requests
.также есть глобальная переменная lastValidRequest
, которая хранит метку времени последнего Request
объекта, который фактически изменил DOM
.В функции обратного вызова я проверяю, было ли отправлено Request
, чья временная метка меньше lastValidRequest
, и отбрасываю эти запросы, потому что они старые и новее 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
ответ:
["gaga",["GaGa","GAGA","Gagarin's Start","Gagauz people","Gagauzia","Gaga","Gagaku","Gagauz language","Gagarin","Gagan Narang"]]
Теперь я могу легко определить, какой ответ принадлежит какому запросу.Таким образом, я могу сделать что-то вроде этого, чтобы увидеть, отвечает ли ответ на самый последний запрос
if (textbox.value==data[0]) //check if searchbox's value is same as JSON's first element
{
//update dom because response its for latest request
}
, но именно то, что я ищу, это
КАК Я АССОЦИИРУЮ АЗАПРОС С ОТВЕТОМ В ОБЩЕМ?
то есть как я могу решить, какой ответ принадлежит какому запросу ( Я за гипотезы? )