Javascript 如何限制并发执行?

Javascript 如何限制并发执行?,javascript,node.js,request,Javascript,Node.js,Request,我想下载70张图片。它们的完整大小约为100mb 这是我代码的简化部分 function downloadImage(src){ var dst = '...'; request(src).pipe(fs.createWriteStream(dst)); return dst; } arrayOf70.forEach(function(e){ var thing = new Thing({ // ... image: downlo

我想下载70张图片。它们的完整大小约为100mb

这是我代码的简化部分

function downloadImage(src){
    var dst = '...';
    request(src).pipe(fs.createWriteStream(dst));
    return dst;
}

arrayOf70.forEach(function(e){
    var thing = new Thing({
        // ...
        image: downloadImage(url)
    });
    thing.save();
}
问题是有太多的并发下载。好的,第一步:为请求传递一个巨大的超时

request({url: src, timeout: 120000000}).pipe(fs.createWriteStream(dst));
好吧,由于它超过了操作系统TCP超时时间,所以效果不太好。至少我认为这是问题所在。不管怎样,我的连接超时了

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: connect ETIMEDOUT
    at exports._errnoException (util.js:746:11)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1000:19)

所以。如何限制并发下载量

下面是一个setInterval示例:

var array_length = arrayOf70.length;
var i = 0;

var request_interval = setInterval(makeRequest, 100);

function makeRequest()
   if(i<array_length){
      var thing = new Thing({
         // ...
         image: downloadImage(url)
      });
      thing.save();
      i++;
   }else{
      clearInterval(request_interval);
   }
},100);
var array_length=arrayOf70.length;
var i=0;
var请求间隔=设置间隔(makeRequest,100);
函数makeRequest()

如果(i超时不是一个理想的解决方案。你真正需要的是能够等待下载完成,然后立即开始新的下载。这是一个特定的并行次数。 您可以通过使用回调来实现这一点

function downloadImage(src, callback){
  var dst = '...';
  http.get(src, function(res) {
    res.pipe(fs.createWriteStream(dst))
      .on("finish", function() {
        callback(dst);
    });
  });
}    
function downloadAllImages(array) {
  var idx = 0;

  function downloadLoop() {
    if(idx >= array.length) return;
    downloadImage(array[idx++], function(dst) {
      var thing = new Thing({
          // ...
          image: dst
      });
      thing.save();
      downloadLoop();
    });
  }

  for(var i = 0; i < 5; i++) downloadLoop(); //start 5 concurrent download "loops"
}
函数下载映像(src,回调){
var dst='…';
get(src,函数(res){
res.pipe(fs.createWriteStream(dst))
.on(“完成”,函数(){
回拨(dst);
});
});
}    
函数下载图像(数组){
var-idx=0;
函数downloadLoop(){
if(idx>=array.length)返回;
下载图像(数组[idx++],函数(dst){
新事物({
// ...
图片:dst
});
save();
下载循环();
});
}
对于(var i=0;i<5;i++)downloadLoop();//启动5个并发下载“循环”
}
为什么不使用setInterval()在每个请求之后几毫秒发出请求?