【问题标题】:NodeJs Readable Error When Reading From Stream从流中读取时NodeJs可读错误
【发布时间】:2019-03-07 07:22:44
【问题描述】:

我想每 1 秒打印一次输出,但出现以下错误。我认为 read 方法是同步调用的,但似乎并非如此。谁能解释一下 read 方法是如何执行的以及为什么会出现这个错误?

const {Readable} = require('stream');

var out = new Readable({

    read(size){
        console.log('read');

        setTimeout(()=>{


        console.log(this.k);

        console.log('before push');

        this.push(String.fromCharCode(this.k++)+'\n');

        console.log('after push\n');
        if(this.k>65){
            this.push(null);
            console.log('null\n');
        }

    },1000);


    }

});
out.k = 65;
out.pipe(process.stdout);

我得到了这个错误:

events.js:183
      throw er; // Unhandled 'error' event
      ^
    Error: stream.push() after EOF
        at readableAddChunk (_stream_readable.js:240:30)
        at Readable.push (_stream_readable.js:208:10)
        at Timeout.setTimeout [as _onTimeout] (C:\Users\x90540\Node\index.js:106:14)
        at ontimeout (timers.js:475:11)
        at tryOnTimeout (timers.js:310:5)
        at Timer.listOnTimeout (timers.js:270:5)

【问题讨论】:

  • 它对我有用,无法重现错误。 BTW setTimeout 使执行异步。
  • 是的,我也试过了。无法复制。
  • @AakashMalhotra Iam 使用节点版本 8.9.4
  • @Dolby 哦,好吧,让我检查一下那个版本。我正在使用最新的 LTS。
  • @AakashMalhotra tpcg.io/hZPSNr 在这里查看

标签: node.js node-streams


【解决方案1】:

当您推送null 时,您正在关闭流,但您没有清除超时,因此您正在尝试在关闭的流上写入。试试这样:

const { Readable } = require('stream');

var prevTimeout;
var out = new Readable({

    read(size) {

        prevTimeout = setTimeout(()=> {

            console.log(this.k);

            this.push(String.fromCharCode(this.k++)+'\n');

            if (this.k > 67) {

                this.push(null);

                clearTimeout(prevTimeout);
            }
        },
        500);
    }
});

out.k = 65;

out.pipe(process.stdout);

有关流的更多信息:https://nodejs.org/api/stream.html#stream_readable_streams

【讨论】:

  • 如果满足条件,这意味着我们想要完成我们的流并且不会执行其他回调(setTimeout)。当没有其他回调时,我如何尝试在流上写入?
  • setTimeout 添加到事件循环的末尾
  • 因此,您要确保在关闭流时也停止执行超时。这正是 clearTimeout 所做的。
  • - nodeJS 多次调用 read 函数。您可以在此处阅读更多信息 nodejs.org/api/stream.html#stream_readable_streams - 尝试运行相同的代码,但不要像 Alex 建议的那样超时。你会看到 read 被多次调用。 - 可能在执行当前调用 read 函数时,之前调用 read 添加的 settimeout 尚未执行。有关这方面的更多信息,您应该阅读更多关于事件循环在 JS 中的工作原理
  • @Dolby 我想我找到了 :) 阅读:github.com/nodejs/node/issues/3203#issuecomment-355137794
【解决方案2】:

对于以后阅读本文的任何人:

如果您使用 Node.js 的更新版本,此行为将不会重现。可以在此处找到对此的详细讨论:

https://github.com/nodejs/node/issues/3203#issuecomment-355137794

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2016-05-28
    • 2022-01-09
    • 2023-03-05
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多