【问题标题】:Wait when equivalent request is pending等待等效请求待处理
【发布时间】:2014-09-16 15:58:05
【问题描述】:

我有这个代码:

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

【问题讨论】:

标签: javascript xmlhttprequest queue


【解决方案1】:

添加一个数组变量,您可以将请求推送到等待。然后在你原来的回调中,如果数组中有一个项,则抓取第一个,将其从数组中删除,然后调用 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() 不必等待队列处理逻辑。

【讨论】:

  • 是的,但总是需要返回回调结果。可能在一个 getData 范围实例内等待?
  • @Deep 抱歉,我想我有点困惑——sendGetRequest 回调在每次调用时都在执行return callback();。也许我误解了你的评论?
  • oops.. )) 是的,这是我的失败。是的,这必须等待并等待 sendGetRequest 的回调。好吧,这是愚蠢的逻辑。需要重写这段代码。感谢您的帮助!
猜你喜欢
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 2016-12-08
  • 2017-08-02
  • 2018-08-05
  • 2017-07-30
相关资源
最近更新 更多