簡體   English   中英

Node.js強制等待功能完成

[英]Node.js Force to Wait for Function to Finish

我正在使用Node.js運行的程序中存在for循環。 函數是xray包中的x(),我正在使用它來從網頁上抓取並接收數據,然后將該數據寫入文件。 該程序在用於刮擦〜100頁時是成功的,但是我需要刮擦〜10000頁。 當我嘗試刮取大量頁面時,將創建文件,但它們不保存任何數據。 我相信存在此問題是因為for循環在繼續進行下一次迭代之前沒有等待x()返回數據。

有沒有辦法讓節點在繼續下一次迭代之前等待x()函數完成?

//takes in file of urls, 1 on each line, and splits them into an array. 
//Then scrapes webpages and writes content to a file named for the pmid number that represents the study
 
//split urls into arrays
var fs = require('fs');
var array = fs.readFileSync('Desktop/formatted_urls.txt').toString().split("\n");


var Xray = require('x-ray');
var x = new Xray();
 
for(i in array){
        //get unique number and url from the array to be put into the text file name
                number = array[i].substring(35);
                url = array[i];


        //use .write function of x from xray to write the info to a file
        x(url, 'css selectors').write('filepath' + number + '.txt');
                               
}

注意:我要抓取的某些頁面沒有返回任何值

您不能讓for循環等待異步操作完成。 要解決此類問題,您必須進行手動迭代,並且需要連接到異步操作的完成功能。 以下是工作原理的概述:

var index = 0;
function next() {
    if (index < array.length) {
        x(url, ....)(function(err, data) {
            ++index;
            next();
        });
    }
}
next();

或者,也許是這樣;

var index = 0;
function next() {
    if (index < array.length) {
        var url = array[index];
        var number = array[i].substring(35);
        x(url, 'css selectors').write('filepath' + number + '.txt').on('end', function() {
            ++index;
            next() 
        });
    }
}
next();

代碼的問題是您沒有等待將文件寫入文件系統。 與逐個下載文件相比,一種更好的方法是一次性完成文件,然后等待文件完成,而不是逐個處理它們,然后再進行下一步。

推薦的用於處理Node.js中的Promise的庫之一是bluebird。

http://bluebirdjs.com/docs/getting-started.html

在更新后的示例中(請參見下文),我們遍歷所有URL並開始下載,並跟蹤承諾,然后在寫入文件后便解決了每個承諾。 最后,我們只是等待使用Promise.all()解決所有承諾

這是更新的代碼:

var promises = [];
var getDownloadPromise = function(url, number){
    return new Promise(function(resolve){
        x(url, 'css selectors').write('filepath' + number + '.txt').on('finish', function(){
            console.log('Completed ' + url);
            resolve();
        });
    });
};

for(i in array){
    number = array[i].substring(35);
    url = array[i];

    promises.push(getDownloadPromise(url, number));                               
}

Promise.all(promises).then(function(){
    console.log('All urls have been completed');
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM