等待等效请求待处理时

时间:2014-09-16 15:58:06

标签: javascript xmlhttprequest queue

我有这段代码:

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的包装器。有用。但... 如何等待等效请求完成并返回回调?

1 个答案:

答案 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()不必等待队列处理逻辑。