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"))