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');
}
注意:我正在抓取的一些页面没有返回任何值
您的代码的问题是您没有等待将文件写入文件系统。比一个接一个地下载文件更好的方法是一次完成,然后等待它们完成,而不是在继续下一个之前逐个处理它们。
在nodejs中处理promise的推荐库之一是bluebird。
http://bluebirdjs.com/docs/getting-started.html
在更新后的示例中(见下文),我们遍历所有url并开始下载,并跟踪promise,然后在编写完文件后,解析每个promise。最后,我们只需等待所有的承诺,就可以使用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');
});
不能让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();
相关文章:
- 如何在jqGrid中使saveRow函数等待editRow函数
- 让 JavaScript 函数等待 Jquery 对话框模态的结果
- 如何在函数完成后使用 jQuery 进行动画处理 - 让第二个函数等待
- 如何使函数等待回调完成
- 让jquery函数等待它'的上一个呼叫已解决
- Javascript/jQuery使函数等待回调后再继续
- 让一个函数等待另一个变量
- 如何强制异步函数等待,直到完成
- 使函数等待/暂停;直到另一个结束
- 需要函数等待事件处理程序完成后再执行下一个函数
- Javascript函数等待另一个函数完成
- Javascript:让函数等待查询完成
- 我需要把'return'casper.then'块,让父函数等待子函数完成执行
- 使函数等待直到元素存在
- 美元.Ajax成功函数等待
- 如何让我的javascript函数等待html元素渲染
- 如何强制函数等待某个事件发生
- javascript/jquery:迭代调用函数;等待之前的通话结束
- 如何让JS函数等待执行
- 如何让NodeJs函数等待