javascript - fs.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', '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/

相关文章:

node.js - 我可以使用 require 获取 createSagaMiddleware 吗?

javascript - 如何在 javascript 中的音频 blob 上设置编解码器、采样率和比特率?

javascript - 你如何称呼一个带有函数的对象

javascript - 如何在加载惰性加载的路由组件时显示 "loading"动画?

JavaScript - var self = this; self 未定义

Node.js:给定 URL 数组,确定哪些是有效的

c# - 带超时的 ASP.NET MVC 2 异步操作

javascript - AJAX:异步将文件发布到服务器

javascript - 自动保存用户输入的内容——最聪明的实现方式?

Javascript 循环遍历图像