node.js 初学者:
node.js 应用程序从大约 30 个 URL 的列表中抓取链接数组 (linkArray)。
每个域名/url都有一个对应的(name).json文件,用于检查抓取的链接是否是新的。
获取所有页面,将链接抓取到数组中,然后传递到:
function checkLinks(linkArray, name){
console.log(name, "checkLinks");
fs.readFile('json/'+name+'.json', 'utf8', function readFileCallback(err, data){
if(err && err.errno != -4058) throw err;
if(err && err.errno == -4058){
console.log(name+'.json', " is NEW .json");
compareAndAdd(linkArray, {linkArray: []}.linkArray, name);
}
else{
//file EXISTS
compareAndAdd(linkArray, JSON.parse(data).linkArray, name);
}
});
}
compareAndAdd() 读取:
function compareAndAdd(arrNew, arrOld, name){
console.log(name, "compareAndAdd()");
if(!arrOld) var arrOld = [];
if(!arrNew) var arrNew = [];
//compare and remove dups
function hasDup(value) {
for (var i = 0; i < arrOld.length; i++)
if(value.href == arrOld[i].href)
if(value.text.length <= arrOld[i].text.length) return false;
arrOld.push(value);
return true;
}
var rArr = arrNew.filter(hasDup);
//update existing array;
if(rArr.length > 0){
fs.writeFile('json/'+name+'.json', JSON.stringify({linkArray: arrOld}), function (err) {
if (err) return console.log(err);
console.log(" "+name+'.json UPDATED');
});
}
else console.log(" "+name, "no changes, nothing to update");
return;
}
checkLinks() 是程序挂起的地方,速度令人难以置信慢。我知道 fs.readFile 每秒被多次点击,但在我看来,少于 30 次点击似乎相当微不足道:假设这是一个用于向(可能)数百万用户提供数据的函数。我对 fs.readFile 的期望是否过高,或者(更有可能)是否有另一个组件(例如 writeFile,或完全其他的东西)锁定了所有内容。
补充:
使用 write/readFileSync 会产生很多问题:该程序本质上是异步的,因为它首先向外部网站发出请求,响应时间差异很大,并且读/写会经常发生冲突。上面的函数确保只在读取给定文件后才进行写入。 (虽然很慢)
此外,该程序不会自行退出,我不知道为什么。
编辑
我重新设计了程序,先同步读取,最后同步写入,整个过程缩短到约 12 秒。显然,多次调用 fs.readFile 时会挂起。我不明白何时/如何使用异步 fs,如果多次调用会挂起该函数。
最佳答案
所有异步 fs
操作都在 libuv 线程池内执行,该线程池的默认大小为 4(可以通过将 UV_THREADPOOL_SIZE
环境变量设置为不同的值来更改) 。如果线程池中的所有线程都忙,任何 fs
操作都会排队。
我还应该指出,fs
并不是唯一使用线程池的模块,dns.lookup()
( Node 内部使用的默认主机名解析方法) )、异步 zlib
方法、crypto.randomBytes()
以及 IIRC 的其他一些内容也使用 libuv 线程池。这只是需要记住的事情。
关于javascript - fs.readFile 非常慢,我是否发出了太多请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42321861/