Home > database >  the behavior of returned function by binding console.log to console in the context of a child proces
the behavior of returned function by binding console.log to console in the context of a child proces

Time:01-05

p = require('child_process').spawn('sleep', ['100']);

//cp.on('exit', ()=>{console.log('exited')});
cp.on('exit', console.log.bind(console,'exited'));

//cp.on('close',()=> {console.log('closed')});
cp.on('close',console.log.bind(console,'closed'));

setTimeout(()=>{cp.kill()}, 500)

when I run the code with node, the output is:

exited null SIGTERM
closed null SIGTERM

I know bind returns a new function with the first argument as its this context and the rest of them as its parameters.

if I replace commented lines with the line below them, there will be no null SIGTERM in the output. why?

CodePudding user response:

When you use bind(), the arguments you supply are inserted before any arguments provided by the caller. When child_process calls the exit and close event handlers, it passes the process's termination reason as the argument. Since console.log() prints all its arguments, this reason it printed after the value that you used in the bind() call.

It's roughly equivalent to this:

cp.on('exit', (...args) => console.log('exited', ...args));

CodePudding user response:

Maybe you meant the opposite, the commented lines will just print exited and closed in the output, while the not commented lines will print exited null SIGTERM and closed null SIGTERM.

This happens because console.log is a variadic JavaScript function, this means it accepts an indefinite number of parameters and it will show all of them in the output:

console.log('a', 42, {});

The cp.on function is calling the callback with two parameters, the first parameter is the (eventual) error, while the second parameter is the actual data.

When you use console.log.bind(console, 'exited'), it will create a new function that has console as this and exited as the first parameter. You can eventually call this function with other parameters:

const fn = console.log.bind(console, 'Hello')
fn('World!') // it will print 'Hello, World!'

If you pass this newly created function as the callback of cp.on, the parameters of the callback will be added just after the single parameter that you inserted.

On the other hand, if you pass () => console.log('exited') as the callback of cp.on, the parameters of the callback will be ignored, and you will always receive exited in the output.

If you want the bind complementary behaviour, you can use the spread operator:

cp.on('close',(...params)=> {console.log('closed', ...params)});

CodePudding user response:

As @Barmar Said the bind() inserts before the caller returning any argument in form of any data or code.
Usually it Returns a reference to the EventEmitter, so that calls can be chained.You can use emitter.prependListener() method to add the event listener to the beginning of the listeners array.

What you can do something like below

const emitter = new EventEmitter();
emitter.on('exit', () => console.log('value1'));
emitter.prependListener('exit', () => console.log('value2'));
emitter.emit('exit');

The Above program prints in the following order

Output:
value2
value1

Or you can invoke a anonymous function like this way
child.on("foo",()=> console.log("BLA"))

  • Related