【问题标题】:Node and Lazy: How do I know when it's done?节点和懒惰:我怎么知道它什么时候完成?
【发布时间】:2012-06-20 11:03:41
【问题描述】:

我需要逐行读取文件,并相应地更改变量。 我通常会用 PHP 写这个……但我决定接受挑战。

我写道:

fs = require('fs');
Lazy = require('lazy');
path = require('path');

files = fs.readdirSync('.');
var software = {};


files.forEach( function(fileName){


  var m; 
  if( m = fileName.match(/^(.*)\.txt$/) ){
    name = m[1];

    console.log("Processing file: " + fileName);
    software[name] = {};
    console.log("Software 1: %j",software);

    var section = 'unset';
    new Lazy(fs.createReadStream(fileName)).lines.forEach(
      function(line){
        var m;
        line = line + '';
        if( m = line.match(/^([a-zA-Z_]*):$/)){
          section = m[1];
          software[name][section] = '';
          console.log("Switching to section " + m[1]);
          console.log("Software 2: %j",software);
        } else if (line == '.'){
          section = 'unset'
        } else if (line == ''){
          section = 'unset'
        } else { 
          console.log("LINE: " + line) ;
          software[name][section] = software[name][section] + line + "\n";
          console.log("Software 3: %j",software);
        }
      }

    );   
  }

});

console.log("Software 4: %j",software);

除了代码非常丑陋和未优化之外,我遇到了问题,因为当最后一行打印时,“软件”变量尚未填充!我猜 Lazy 是异步的。所以,它基本上可以工作,但是“在以后的某个时候”。这很好,但是......当填充软件变量的重要循环实际上完成时,我该在哪里编写代码?!?

根据要求:可以使用的数据!

只需创建“something.txt”并写入:

name:
Name 1
.

Option 1:
Value 1
.

Option 2:
Value 2
.

Option 3:
Multi
Line
Value
.

Another_section:
Again
.

佣兵团

【问题讨论】:

  • 好问题!你能给我一些简短的示例数据吗?
  • 我的意思是,我可以存储 fs.createReadStream(fileName)).lines.length 并为每一行增加一个计数器,然后当达到行数时调用功能......但这似乎完全疯狂。当然!

标签: javascript node.js iasyncresult


【解决方案1】:

库返回的 Lazy 实例是 EventEmitters,当“一组”操作完成时,它会发出名为 pipe 的事件:

new Lazy(
  ...
).on('pipe', function() {
  // all done
});

修改代码以使用此事件会导致(唯一的更改在底部附近):

fs = require('fs');
Lazy = require('lazy');
path = require('path');

files = fs.readdirSync('.');
var software = {};


files.forEach( function(fileName){


  var m;
  if( m = fileName.match(/^(.*)\.txt$/) ){
    name = m[1];

    console.log("Processing file: " + fileName);
    software[name] = {};
    console.log("Software 1: %j",software);

    var section = 'unset';
    new Lazy(fs.createReadStream(fileName)).lines.forEach(
      function(line){
        var m;
        line = line + '';
        if( m = line.match(/^([a-zA-Z_]*):$/)){
          section = m[1];
          software[name][section] = '';
          console.log("Switching to section " + m[1]);
          console.log("Software 2: %j",software);
        } else if (line == '.'){
          section = 'unset'
        } else if (line == ''){
          section = 'unset'
        } else {
          console.log("LINE: " + line) ;
          software[name][section] = software[name][section] + line + "\n";
          console.log("Software 3: %j",software);
        }
      }

    ).on('pipe', function() {
      console.log("Software 4: %j",software);
    });
  }

});

[编辑]回答您关于我如何找到此信息的问题:

我确实检查过the source file for the project;我知道库有一个sum 方法,可以链接到 Lazy 的实例,以便在最后总结所有内容; code for that method 调用foldrcode for that method 监听名为pipeName 的事件,默认in line 22pipe

【讨论】:

  • 要问...你是怎么知道的?!?我阅读了 Lasy 的文档,并没有从那里弄清楚。就“管道”或“事件”或“发射”而言,那里并没有太多......我的意思是,你是怎么发现的?您是否必须深入研究源代码?
  • 是的,我同意这些文档不是很全面;我非常喜欢 async 作为我选择的流控制库。我已经用一些额外的信息更新了我的答案。
  • 好的,但我的问题是……你是怎么发现的?!? :D
  • @Merc:他在答案末尾添加了解释。
  • 你的意思是我怎么知道它会在那里?嗯,一个不会告诉你什么时候完成的流控制库不是很有用,所以我有点假设那里会有一些东西——此外,像sum 等可链接的方法不会'在那种情况下不起作用。幸运的是,实现是gets re-emitted 的事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2019-07-18
  • 1970-01-01
  • 2017-12-17
  • 2017-01-31
  • 2018-01-21
  • 1970-01-01
相关资源
最近更新 更多