Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript fs.readFile非常慢,我是否提出了太多请求?_Javascript_Node.js_Asynchronous_Readfile - Fatal编程技术网

Javascript fs.readFile非常慢,我是否提出了太多请求?

Javascript fs.readFile非常慢,我是否提出了太多请求?,javascript,node.js,asynchronous,readfile,Javascript,Node.js,Asynchronous,Readfile,node.js初学者在此: 一个node.js应用程序从大约30个URL的列表中刮取一个链接数组(linkArray) 每个域/url都有一个对应的(name).json文件,用于检查刮取的链接是否是新的 获取所有页面,将链接刮入数组,然后传递给: function checkLinks(linkArray, name){ console.log(name, "checkLinks"); fs.readFile('json/'+name+'.json', 'u

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);
        }
    });
}
compareAndad()读取:

函数compareAndAdd(arrNew、arrOld、name){
log(名称为“compareAndAdd()”);
如果(!arrOld)变量arrOld=[];
如果(!arrNew)变量arrNew=[];
//比较并删除DUP
函数hasDup(值){
对于(变量i=0;i
checkLinks()是程序挂起的地方,它的速度慢得令人难以置信。我知道fs.readFile每秒会被点击多次,但我知道点击次数不到30次似乎很简单:假设这是一个用于向(可能)数百万用户提供数据的函数。我是否对fs.readFile期望过高,或者(更有可能)是否有另一个组件(如writeFile或其他完全相同的组件)将所有内容都锁定

补充:

使用write/readFileSync会产生很多问题:这个程序本质上是异步的,因为它从外部网站的请求开始,响应时间变化很大,读/写会经常发生冲突。上面的函数确保只在读取给定文件之后才对其进行写操作。(尽管速度非常慢)

而且,这个程序不会自行退出,我也不知道为什么

编辑
我重新编写了程序,先读后同步写,进程缩短到12秒。显然,fs.readFile在多次调用时被挂起。如果多个调用挂起函数,我不知道何时/如何使用异步fs。

所有异步
fs
操作都在libuv threa内执行d池,默认大小为4(可以通过将
UV\u THREADPOOL\u size
环境变量设置为其他变量来更改)。如果线程池中的所有线程都很忙,则任何
fs
操作都将排队


我还应该指出,
fs
不是唯一使用线程池的模块,
dns.lookup()
(节点内部使用的默认主机名解析方法)、async
zlib
方法、
crypto.randomBytes()
,IIRC还使用了libuv线程池。这只是需要记住的一点。

所有异步
fs
操作都是在libuv线程池内执行的,libuv线程池的默认大小为4(可以通过将
UV\u THREADPOOL\u size
环境变量设置为不同的值来更改)。如果线程池中的所有线程都忙,则任何
fs
操作都将排队

我还应该指出,
fs
不是唯一使用线程池的模块,
dns.lookup()
(节点内部使用的默认主机名解析方法)、async
zlib
方法、
crypto.randomBytes()
,IIRC还使用了libuv线程池。这只是需要记住的一点。

如果在循环中读取了许多文件(检查链接),首先会调用所有的
fs.readFile
函数。只有在调用之后才会处理回调(仅当主函数堆栈为空时才会处理回调).这将导致启动延迟。但不要担心这一点

您指出一个程序永远不会结束。因此,请创建一个计数器,统计对
checkLinks
的调用,并在调用回调函数后减少计数器。在回调中,根据0检查计数器,然后执行终结逻辑(我怀疑这可能是对http请求的响应)

实际上,无论您使用的是异步版本还是同步版本,它们都将在相对相同的时间工作。

如果您在一个循环中读取了许多文件(检查链接),首先将调用所有的
fs.readFile
函数。并且只有在这之后才会处理回调(仅当主函数堆栈为空时才处理它们).这将导致启动延迟。但不要担心这一点

您指出一个程序永远不会结束。因此,请创建一个计数器,统计对
checkLinks
的调用,并在调用回调函数后减少计数器。在回调中,根据0检查计数器,然后执行终结逻辑(我怀疑这可能是对http请求的响应)


实际上,使用异步版本还是同步并不重要。它们的工作时间相对相同。

FYI,在异步回调中执行
throw err
不会对您有任何好处,因为无法捕获该抛出。您需要在一些
console.log()中对每个
fs.readFile()
进行计时
并查看它们是否都很慢,或者只有后面的那些很慢,因为线程池很忙,因此您正在等待。我建议输出每个
fs.readFile()
操作所需的确切时间。与
fs.writeFile()相同
。我们需要看看这是否只是一个线程池争用问题,或者您的读/写速度是否因为某种原因而变慢。另外,当您说“难以置信的慢”时,我们谈论的时间是多少?@jfriend00>4分钟。这些文件有多大?前几次读写是否快了很多?仅供参考,在异步回调中执行
throw err
不会对您有任何好处,因为无法捕捉到该抛出。您需要在某些时间内对每个
fs.readFile()
进行计时
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;
}