首页 > 解决方案 > 在 NodeJS 的底层,在哪里以及如何调用 readable._read()?

问题描述

我对下面的程序非常好奇。该程序仅在消费者请求时将字母“a”到“z”(包括)推送到可读流中。我从文档中了解到_read()实现是由内部Readable类方法调用的。如果您使用该命令从终端运行该程序,node app.js | head -c5那么我们可以看到_read()当我们只请求 5 个字节时它只被调用了 5 次,因此它只打印abcde

我想知道这个_read()实现在 Node 源代码中的哪个位置被调用?或者_read()当我们请求 5 个字节的数据时,Node 源代码中的哪里被调用了 5 次?

我很想知道这一点,如果有人可以帮助我弄清楚那将是很棒的。

var Readable = require('stream').Readable;
var rs = Readable();

var c = 97 - 1;

rs._read = function () {
    if (c >= 'z'.charCodeAt(0)) return rs.push(null);
    
    setTimeout(function () {
        rs.push(String.fromCharCode(++c));
    }, 100);
};

rs.pipe(process.stdout);

process.on('exit', function () {
    console.error('\n_read() called ' + (c - 97) + ' times');
});
process.stdout.on('error', process.exit);

标签: node.jsnodejs-stream

解决方案


管道功能是触发点。

  • 当您调用pipe函数时,会on('data', ...)触发一个事件。
  • _read此事件使用您的实现为流提取数据。
  • 现在您的可读流已填充数据。

关于head指挥,

  • 该命令查找输出实用程序-c字符。假设head -c 5一旦打印了 5 个字符,它就表示前一个进程退出。
  • 收到此信号后,节点进程运行 exit 函数并终止,因此停止_read进一步执行并打印在此之前读取的字符数。

这是从 VS Code 中捕获的 _read 函数的调用堆栈:

在此处输入图像描述


推荐阅读