7

我有一个数组。我可以用 foreach 方法循环它。

data.forEach(function (result, i) {

     url = data[i].url;

     request(url);

});

request 函数正在向给定的 url 发出 http 请求。然而,同时提出所有这些请求会导致各种问题。

所以我想我应该通过引入某种计时器来减慢速度。

但我不知道如何将 forach 循环与 setTimeOut/setInterval 结合起来

请注意我在服务器(nodejs)而不是浏览器上执行此操作。

谢谢你的帮助。

4

6 回答 6

8

由于您的问题是全球性的,您应该调整您的request函数以一次只运行 5 个请求 - 使用全局静态计数器。如果您的请求是在类似之前

function request(url, callback) {
    ajax(url, callback);
}

现在使用类似的东西

var count = 0;
var waiting = [];
function request(url, callback) {
    if (count < 5) {
        count++;
        ajax(url, function() {
            count--;
            if (waiting.length)
                request.apply(null, waiting.shift());
            callback.apply(this, arguments);
        });
    } else
        waiting.push(arguments);
}
于 2012-09-24T19:54:00.700 回答
5
data.forEach(function (result, i) {

     url = data[i].url;

     setTimeout(
         function () {
              request(url);
         }, 
         1000 * (i + 1) // where they will each progressively wait 1 sec more each
     );

 });
于 2012-09-24T19:42:13.260 回答
3

而不是setTimeout让它们按顺序运行。我假设callback你的函数有一个参数request()

function makeRequest(arr, i) {
    if (i < arr.length) {
        request(arr[i].url, function() { 
                                i++; 
                                makeRequest(arr, i); 
                            });
    }
}

makeRequest(data, 0);

如果您在请求之间需要更多时间,则将 添加setTimeout到回调中。

function makeRequest(arr, i) {
    if (i < arr.length) {
        request(arr[i].url, function() { 
                                i++; 
                                setTimeout(makeRequest, 1000, arr, i); 
                            });
    }
}

makeRequest(data, 0);
于 2012-09-24T19:44:45.553 回答
1

您可以使用 setTimeout 延迟通话。以下代码将确保每个请求在timerMultiPlier其前一个请求的毫秒后被调用。

var timerMultiPlier = 1000;
data.forEach(function (result, i) {
     setTimeout(function(){
           url = data[i].url;         
           request(url);
   }, timerMultiPlier*i );

});
于 2012-09-24T19:42:00.853 回答
0

您可以通过索引抵消每个项目的执行延迟,如下所示:

data.forEach(function (result, i) { 
  setTimeout(function() {
    url = data[i].url; 
    request(url);
  }, i * 100);
}); 

这将使每次迭代在前一次迭代之后执行大约 100 毫秒。您可以更改100为您喜欢的任何数字来更改延迟。

于 2012-09-24T19:42:39.887 回答
0

上述许多解决方案虽然对一些请求很实用,但在处理数以万计的请求时不幸地阻塞并阻塞了页面。与其将所有计时器排在一个队列中,不如将每个计时器一个接一个地依次排入队列。如果您的目标是编写包含大量糖和“好东西”的漂亮蓬松代码,那么以下是适合您的解决方案。

function miliseconds(x) { return x }
function onceEvery( msTime ){
    return {
        doForEach: function(arr, eachF){
            var i = 0, Len = arr.length;
            (function rekurse(){
                if (i < Len) {
                    eachF( arr[i], i, arr );
                    setTimeout(rekurse, msTime);
                    ++i;
                }
            })();
        }
    };
}

漂亮、漂亮、蓬松的糖衣用法:

onceEvery(
    miliseconds( 150 )
).doForEach(
    ["Lorem", "ipsum", "dolar", "un", "sit", "amet"],
    function(value, index, array){
        console.log( value, index );
    }
)

function miliseconds(x) { return x }
function onceEvery( msTime ){
    return {
        doForEach: function(arr, eachF){
            var i = 0, Len = arr.length;
            (function rekurse(){
                if (i < Len) {
                    eachF( arr[i], i, arr );
                    setTimeout(rekurse, msTime);
                    ++i;
                }
            })();
        }
    };
}

于 2018-04-07T01:53:25.410 回答