Javascript 队列URL和异步代码

Javascript 队列URL和异步代码,javascript,arrays,node.js,asynchronous,queue,Javascript,Arrays,Node.js,Asynchronous,Queue,我有以下代码,我使用wappalyzer来获取网站的技术数据 const wappalyzer = require('wappalyzer'); var fs = require('fs'); var myArray =[http://www.url1.com, http://www.url2.com ...] // it's a very long array of URLs var dataSlice = myArray.slice(0, 1000); console.log

我有以下代码,我使用wappalyzer来获取网站的技术数据

const wappalyzer = require('wappalyzer');
var fs = require('fs');

var myArray =[http://www.url1.com, http://www.url2.com ...]   // it's a very 
long array of URLs

var dataSlice = myArray.slice(0, 1000);  

console.log(dataSlice);
fs.appendFileSync('webData.json', '[', 'utf8');

var done = {};
var count = 0;
for(i = 0; i < dataSlice.length; i++) {
  (function(i){
    wappalyzer.run([dataSlice[i], '--quiet'], function(stdout, stderr) {
      //Keep track of when all urls are done

      if(!done[i]){
        done[i] = true;
        count++;

        if ( stdout ) {
          var arr = stdout.split('\n');
          stdout  = arr.filter(function(elem, pos) {
              return arr.indexOf(elem) == pos;
          });
          stdout = stdout.join('');
          stdout = count >= dataSlice.length ? (stdout + ']') : (stdout + 
',');
          fs.appendFileSync('WebData.json', stdout, 'utf8');
        }

      }

      if ( stderr ) {
        process.stderr.write(stderr);
      }
    });
  })(i);
}
const wappalyzer=require('wappalyzer');
var fs=需要('fs');
变量myArray=[http://www.url1.com, http://www.url2.com …]//这是一个非常重要的问题
长URL数组
var-dataSlice=myArray.slice(0,1000);
console.log(数据许可证);
appendFileSync('webData.json','[','utf8');
var done={};
var计数=0;
对于(i=0;i=dataSlice.length?(stdout+']'):(stdout+
',');
appendFileSync('WebData.json',stdout',utf8');
}
}
如果(标准){
process.stderr.write(stderr);
}
});
})(i) );
}

问题是我有一个非常大的URL列表,我在这个循环中运行,所以我将数组分成更小的部分,每次执行~1000次。但是,当我再执行这些操作时,系统会冻结,因为它使用了相当多的CPU,我如何异步运行这些代码并将URL排队?还有一个简单的NPM包可以安装吗?我环顾四周,没有发现任何易于使用的东西。

您可以使用环形缓冲区

其思想是有一个挂起任务的数组,有一个循环(在节点中,循环必须是异步的,以不阻塞引擎),该循环执行重新填充和启动作业的作业,使用回调可以监视任务的开始/结束

注意不要在回调中覆盖环,因为你们会看到我总是从一个调用复制到另一个调用,并同步写入

如果我是正确的,下面应该做这项工作

// concurrent/async job processing.
function main() {

  var consumer = function(todo, done){ // execute whatever to do.
    console.log("start ", todo.id, todo.duration);
    setTimeout(function(){
      done();
      console.log("done ", todo.id, todo.duration);
    }, todo.duration);
  };

  var id = 0;
  function reader(len) { // a dummy function that provides n new jobs
    var ret = []
    for(i=0;i<len;i++){
      ret.push({
        id: id,
        duration:getRandomInt(250, 1000),
        about: "whatever todo",
        status: "todo"
      });
      id+=1;
    }
    return ret
  };

  var ring = []; // the ring contains the element being processed
  var loop = function(){ // is async
    ring = processor(ring, 10, reader, consumer);
    logger(ring);
    setTimeout(loop, 100); // loop here.
  };loop();

};process.nextTick(main);

function processor(ring, concurrency, reader, consumer){
  ring = ring.filter(notStatus('done')); // remove done jobs
  var delta = concurrency-ring.length;
  if(delta>0) { // refill the ring until it is full
    ring = ring.concat(reader(delta))
  }
  ring.filter(byStatus('todo')).forEach(function(todo){ // select those todo
    todo.status = 'started';
    consumer(todo, function(){
      todo.status = "done";
    })
  })
  return ring
}

function logger(ring){
  console.log("   ring");
  ring.forEach(function(todo){
    console.log("   ", todo.status, todo.id, todo.duration);
  });
}

function byStatus(s){
  return function(todo){return todo.status==s}
}

function notStatus(s){
  return function(todo){return todo.status!=s}
}

// .... still not std ?
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
//并发/异步作业处理。
函数main(){
var consumer=函数(todo,done){//执行要执行的任何操作。
日志(“开始”,todo.id,todo.duration);
setTimeout(函数(){
完成();
日志(“完成”,todo.id,todo.duration);
}、待办事项、持续时间);
};
var-id=0;
函数读取器(len){//提供n个新作业的伪函数
var ret=[]
对于(i=0;i0){//重新填充环,直到其充满为止
环=环浓度(读卡器(增量))
}
过滤器(byStatus('todo')).forEach(函数(todo){//选择那些todo
todo.status='started';
消费者(todo,函数(){
todo.status=“完成”;
})
})
回程环
}
功能记录器(环){
控制台日志(“环”);
ring.forEach(函数(todo){
console.log(“”,todo.status,todo.id,todo.duration);
});
}
状态函数(s){
返回函数(todo){return todo.status==s}
}
功能状态{
返回函数(todo){return todo.status!=s}
}
//还是不是性病?
函数GetRandomArbital(最小值、最大值){
返回Math.random()*(max-min)+min;
}
函数getRandomInt(最小值、最大值){
返回Math.floor(Math.random()*(max-min+1))+min;
}

也许async/await+Promissions会有所帮助?如果你的节点版本支持itI,我看了bluebird一眼,但不能真正理解它,我是有点新的。你使用什么节点版本?8.1.3我可以通过这个实现吗?async.each(openFiles、saveFile、function(err){//如果任何保存产生了错误,err将等于该错误});可能有效,但我不知道如何用我拥有的代码实现它,我有点想了解我在做什么。将其复制/粘贴到文件
index.js
,适当地更新代码以实现所需,运行
node index.js
。这在浏览器中不起作用。