V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HanningWu
V2EX  ›  Node.js

请问如何使用 nodejs 的 readline 模块按行读取文件内容然后依次更新到 html 页面中?

  •  
  •   HanningWu · 2017-04-03 21:17:11 +08:00 · 7342 次点击
    这是一个创建于 2782 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有个文本文件 cellphone.txt ,有三行内容

    iPhone
    Pixel
    Windows Phone
    

    在HTML文件中,我利用按钮(button)的onclick时间去触发下文中的 js 脚本中包含的函数 startOutput(),这个函数中先创建一个 id 为 outputStream 的段落,然后用 nodejs 里的 readline 模块按行读取 cellphone.txt 文件中的内容,每读取一行就更新到 outputStream 中去,实现顺序显示文件每行内容。但实际运行的时候,并不是依次显示 iPhone ,然后 Pixel ,最后再是 Windows Phone ,而是卡一阵子,然后 outputStream 段落中只显示最后一行内容 Windows Phone 。当然,你可能会说由于你这里只有三行,依次显示的速度太快了,你没看到前两次输出。换成一个拥有1000行内容的文本文件,效果也是卡一阵子,然后只输出最后一行。

    HTML 文件:

    <html>
    <body>
    <script src='output.js'></script>
    
    <button type="button" onclick="startOutput()"></button>
    
    </body>
    </html>
    

    JavaScript 文件:

    //output.js
    
    function startOutput() {
      document.write('<p id="outputStream">初始文本<p>');
      var fs = require('fs');
      var lineReader = require('readline').createInterface({
        input: fs.createReadStream('cellphone.txt') // 建立 txt 文件的读取流
      });
    
       lineReader.on('line', function (line) {  //按行对读取流内容进行操作
         document.getElementById("outputStream").innerHTML(line);
       }
     }
    

    这里并不一定非要用button去触发这个函数。我的主要目的是在 html 页面中,按行显示文件内容(必须要有显示过程,先第一行,再第二行,然后以此类推),如果有其他方法可以实现这一点,欢迎 V 友提出,感谢大家!

    19 条回复    2017-04-06 10:27:48 +08:00
    bdbai
        1
    bdbai  
       2017-04-03 21:24:13 +08:00 via Android
    有点好奇 js 直接调用 nodejs 模块是怎么实现的?
    HanningWu
        2
    HanningWu  
    OP
       2017-04-03 21:28:14 +08:00
    @bdbai 我在 node-webkit 中运行的,所以 js 中可以直接调用 nodejs ,是打算做一个 Web App
    jarlyyn
        3
    jarlyyn  
       2017-04-03 21:31:30 +08:00
    document.getElementById("outputStream").innerHTML(line);

    为什么会显示多行……

    你每次都吧元素的内容设置为当前行啊。

    那最后当然只能看到最后一行了
    qfdk
        4
    qfdk  
       2017-04-03 21:34:07 +08:00 via iPhone
    HanningWu
        5
    HanningWu  
    OP
       2017-04-03 21:35:48 +08:00
    @jarlyyn 我就是每次显示一行啊,但是由于 lineReader.on 这个方法循环了三次,所以对 outputStream 的内容改写了三次,理论上我应该能看到每次改写的变化的。
    bombless
        6
    bombless  
       2017-04-03 21:58:52 +08:00 via Android
    要依赖系统卡住这一点?
    感觉还不如你主动卡住

    setTimeout 等待行数乘以 1000 ,就能慢慢看到显示了
    zbinlin
        7
    zbinlin  
       2017-04-04 00:06:59 +08:00 via Android
    innerHTML 这里怎么是一个函数来的?
    HanningWu
        8
    HanningWu  
    OP
       2017-04-04 06:30:27 +08:00
    @zbinlin 更正内容 innerHTML(line) 为 innerHTML = line
    不好意思手快打错了。
    HanningWu
        9
    HanningWu  
    OP
       2017-04-04 06:31:42 +08:00
    @bombless 感谢提示!我去研究一下 setTimeout 函数的使用方法。
    SuperMild
        10
    SuperMild  
       2017-04-04 10:53:50 +08:00
    建议看一下 D3.js ,有控制动态过程的功能。
    123s
        11
    123s  
       2017-04-04 12:07:07 +08:00 via Android
    额,你一次过插入再做动画就好了,不然就要写多不少代码
    bdbai
        12
    bdbai  
       2017-04-04 13:38:07 +08:00 via iPhone
    @qfdk 二楼说了 node-webkit ,没打算谢。
    另外 https://webpack.github.io 不谢
    HanningWu
        13
    HanningWu  
    OP
       2017-04-06 00:38:07 +08:00
    @jarlyyn 最终是需要实现这样一个效果,示例代码: https://jsfiddle.net/09kuyn7v/ 。唯一不同的是,数据不是从数组中读取,而是从文件每一行读取出来,然后以同样的效果通过点击按钮显示到 html 的一个段落中去。
    jarlyyn
        14
    jarlyyn  
       2017-04-06 00:44:41 +08:00
    @HanningWu

    所以你应该先把数据取出来压倒这个 list 里
    然后再执行这段动画啊……
    HanningWu
        15
    HanningWu  
    OP
       2017-04-06 00:54:23 +08:00
    @jarlyyn 数据量太大了,内存不够,不能一次性读取到数组中去。只能通过用流式方法读取。。
    jarlyyn
        16
    jarlyyn  
       2017-04-06 01:03:21 +08:00
    @HanningWu

    所以读一批,动画执行完了再去读下一批啊……
    HanningWu
        17
    HanningWu  
    OP
       2017-04-06 09:03:36 +08:00 via iPhone
    @jarlyyn 我也是这么想的,所以后来又问了这个问题: https://www.v2ex.com/t/352731#reply24
    jarlyyn
        18
    jarlyyn  
       2017-04-06 09:57:24 +08:00
    @HanningWu
    请允许我一脸懵逼……

    你不 close 文件继续读不行么……

    或者记录下行号……

    用 fs.read 啊
    HanningWu
        19
    HanningWu  
    OP
       2017-04-06 10:27:48 +08:00
    @jarlyyn 遇到的问题是怎样把用 readline 读出来的内容更新到页面中去显示出来,不要纠结我怎么读取文件了……按你说的加一个 lineReader.close() 反而一条内容都读不出来了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:23 · PVG 23:23 · LAX 07:23 · JFK 10:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.