简体   繁体   中英

setTimeout nuances in Node.js

I'm trying to understand how the callback function works inside the setTimeout function. I'm aware the format is: setTimeout(callback, delay) I wrote a little test script to explore this.

test1.js

console.log("Hello")

setTimeout(function () { console.log("Goodbye!") }, 5000)

console.log("Non-blocking")

This works as expected, printing Hello <CRLF> Non-blocking and then 5 seconds later, prints Goodbye!

I then wanted to bring the function outside of the setTimeout like this:

console.log("Hello")

setTimeout(goodbye(), 5000)

console.log("Non-blocking")

function goodbye () {
    console.log("Goodbye")
}

but it doesn't work and there isn't a 5 second delay between Non-blocking and Goodbye! , they print straight after each other.

It works if I remove the brackets from the function call in the timeout, like this:

setTimeout(goodbye, 5000)

but this doesn't make sense to me because that's not how you call a function. Futhermore, how would you pass arguments to the function if it looked like this?!

var name = "Adam"    

console.log("Hello")

setTimeout(goodbye(name), 5000)

console.log("Non-blocking")

function goodbye (name) {
    console.log("Goodbye "+name)
}

My question is really, why doesn't it work when there are parameters in the function, despite the fact the setTimeout is being provided with a valid function with the correct syntax?

By putting the parentheses after your function name, you are effectively calling it, and not passing the function as a callback.

To provide parameters to the function you are calling:

  1. You can pass an anon function. setTimeout(function(){goodbye(name)}, 5000);
  2. Or, you can pass the arguments as a third parameter. setTimeout(goodbye, 5000, name);

Look at this question: How can I pass a parameter to a setTimeout() callback?

No matter where you place it, goodbye(name) executes the function immediately . So you should instead pass the function itself to setTimeout() : setTimeout(goodbye, 5000, name) .

When you use it like this:

setTimeout(goodbye(), 5000);

it will first call goodbye to get its return value, then it will call setTimeout using the returned value.

You should call setTimeout with a reference to a callback function, ie only specifying the name of the function so that you get its reference instead of calling it:

setTimeout(goodbye, 5000);

To make a function reference when you want to send a parameter to the callback function, you can wrap it in a function expression:

setTimeout(function() { goodbye(name); }, 5000);

You can use parantheses in the call, but then the function should return a function reference to the actual callback function:

setTimeout(createCallback(), 5000);

function createCallback() {
  return function() {
    console.log("Goodbye");
  };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM