Skip to content

strange befavior about console.err,console.log on win10 #18232

Description

@godhand4826
  • Version:v8.4.0
  • Platform: 64-bit (Windows10)
  • Subsystem:

Stackoverflow: a strange behavior about the EventEmitter in node

I am learning EventEmitter. and I have a simple stupid test. (node --version v8.4.0 on win10)

const EventEmitter = require('events');

const emiter1 = new EventEmitter()
const emiter2 = new EventEmitter()

// let cnt = 1

emiter1.on('ping', () => {
    // console.log('ping' + cnt++)
    emiter2.emit('pong')
})

emiter2.on('pong', () => {
    // console.log('pong' + cnt++)
    emiter1.emit('ping')
})

emiter1.emit('ping')

I expect it will become a infinity function call, because emit() is a sync function.
Here is the output.:

$ node em.js
C:\tmp\em.js:13
    emiter2.on('pong', () => {
                    ^

RangeError: Maximum call stack size exceeded
    at EventEmitter.emiter2.on (C:\electron-workspace\tmp\em.js:13:24)
    at emitNone (events.js:105:13)
    at EventEmitter.emit (events.js:207:7)
    at EventEmitter.emiter1.on (C:\electron-workspace\tmp\em.js:10:17)
    at emitNone (events.js:105:13)
    at EventEmitter.emit (events.js:207:7)
    at EventEmitter.emiter2.on (C:\electron-workspace\tmp\em.js:15:17)
    at emitNone (events.js:105:13)
    at EventEmitter.emit (events.js:207:7)
    at EventEmitter.emiter1.on (C:\electron-workspace\tmp\em.js:10:17)

Great! Just as I expected. But after I uncomment the cnt and console.log, I got a strange behavior. The program finished without an error, and stop at cnt==1600 (sometime is 1598, 1599)

$ node em.js
ping1
pong2
ping3
pong4
...
...
pong1596
ping1597
pong1598
ping1599
pong1600

$

Finally, I run node em.js 1> out.txt 2> err.txt and both console.log and console.err are correct just as I expect. But I'm still wondering why the err didn't print out directly in my shell?
Is there a reasonable explanation?

Activity

  1. vsemozhetbyt commented on Jan 18, 2018

    @vsemozhetbyt
    Contributor

    If I get this right, it is because the console.log() is async operation. See:

    https://nodejs.org/api/process.html#process_a_note_on_process_i_o
    https://nodejs.org/api/async_hooks.html#async_hooks_printing_in_asynchooks_callbacks

    You can use this trick from the example of the second reference:

    const fs = require('fs');
    const EventEmitter = require('events');
    
    const emiter1 = new EventEmitter();
    const emiter2 = new EventEmitter();
    
    let cnt = 1;
    
    emiter1.on('ping', () => {
        fs.writeSync(1, `ping${cnt++}\n`);
        emiter2.emit('pong');
    })
    
    emiter2.on('pong', () => {
        fs.writeSync(1, `pong${cnt++}\n`);
        emiter1.emit('ping');
    })
    
    emiter1.emit('ping');
  2. godhand4826 commented on Jan 19, 2018

    @godhand4826
    Author

    thank you very much. I got the clue.

  3. added
    consoleIssues and PRs related to the console subsystem.
    questionIssues asking questions about Node.js.
    on Jan 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    consoleIssues and PRs related to the console subsystem.questionIssues asking questions about Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions