我有这段代码:
var data = {};
var dataPending = {};
function getData(name, callback) {
callback = callback || function() {};
// new response
if (!data[name] && !dataPending[name]) {
dataPending[name] = true;
sendGetRequest({
url : '/blah-blah/' + name,
callback : function(response) {
data[name] = response;
delete dataPending[name];
return callback();
}
});
// equivalent request in progress
} else if (dataPending[name]) {
// TODO how to wait for equivalent request is completed and return callback?
// data is exists
} else {
return callback();
}
}
getData('name1', function() { ... });
getData('name1', function() { ... });
getData('name2', function() { ... });
getData('name2', function() { ... });
getData('name1', function() { ... });
函数sendGetRequest是xmlhttprequest的包装器。有用。但... 如何等待等效请求完成并返回回调?
答案 0 :(得分:0)
添加一个数组变量,您可以将请求推送到等待。然后在原始回调中,如果数组中有一个项目,请抓住第一个项目,将其从数组中删除,然后调用getData。
如,
var dataQueue = [];
var active = false;
function getData(name, callback, force) {
if(active && !!force) {
dataQueue.push({name: name, callback: callback});
}
else {
active = true;
sendGetRequest({
url: '/blah-blah/' + name,
callback : function(response) {
if(dataQueue.length > 0) {
active = false;
}
else {
var reqObj = dataQueue.shift();
getData(reqObj.name, reqObj.callback, true);
}
return callback();
}
});
}
}
基本思想是有一个标志,指示是否正在完成工作,以及一个数组,用于保存我们想要等待发送的请求。当您获取数据时,如果我们已经处理了请求(通过我们的active
标志),请将项目推入队列,否则继续运行并将active设置为true。在sendGetRequest
的回调中,我们会看到dataQueue
是否有任何项目 - 如果它没有,我们将不再处于活动状态,因此请将该标志设置为false。如果有项目,请获取数组的第一项并将其删除。然后在该项上调用getData,将force设置为true,以允许它进行处理。
请注意,在回调中检查队列中是否有项目的逻辑应分解为单独的函数。您可能还希望将其包含在带有0MS的setTimeout
中,以便return callback()
不必等待队列处理逻辑。