2017-07-07 15 views
0

ウェブサイトの技術データをスクラップするために私がwappalyzerで使用する次のコードがあります。キューイングURLと非同期コード

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); 
} 

問題は、私はそれとして、それ以上systemfreezesを行うときに、私は、しかし、時間で1000〜私がやって小さなセクションに、配列をスライス私はこのループを実行したURLの非常に大きなリストを持っていますかなりのCPUを使用していますが、このコードをどのように非同期で実行し、URLをキューに入れるのですか?また、イントールするための簡単なNPMパッケージがありますか?私は周りを見ていて、使いやすいものは見つけられていません。

+0

おそらく、async/await +約束はいくらか助けになることがありますか?あなたがノードのバージョンがそれをサポートしていれば、 – Endless

+0

私はブルーバードを見ましたが、本当に理解できませんでした。 – user3679330

+0

どのノードのバージョンを使用していますか? – Endless

答えて

0

あなたはリングバッファーを行うことができます。

アイデアは保留中のタスクの配列を持つことです。ループを1つ(ノード内ではループはエンジンをブロックしないように非同期でなければなりません)にしてジョブを補充して開始し、コールバックで開始/タスクの終わり。

私はいつもコールからコールにコピーし、それを同期で書き込むことがわかるように、コールバックのリングを上書きしないように注意してください。

私は正しい場合、以下の作業を行う必要があります。

// 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; 
} 
+0

おそらく動作しますが、私が持っているコードで実装する方法がわかりませんし、私がやっていることを理解したいと思っています。 – user3679330

+0

ファイルを 'index.js'ファイルにコピー&ペーストし、必要に応じてコードを適切に更新し、' node index.js'を実行します。それはブラウザではうまくいきませんでした。 –

関連する問題