为什么我不能将函数调用(而不是函数引用或匿名函数)传递给setTimeout()?

时间:2017-04-10 07:29:57

标签: javascript functional-programming

请忽略这样一个事实:这段代码没有任何结果,并为可能是一个无聊的问题道歉!

我理解我不能将函数调用作为第一个参数传递给setTimeout(),但为什么我不能这样做?

let names = ['Andy', 'Ross', 'David'];

function printer (name) {
 console.log(name);
}

names.forEach(name => setTimeout(printer(name), 1000);

结果:

Andy
timers.js:327
    throw new TypeError('"callback" argument must be a function');
    ^

我可以通过使用对printer的引用并使用bind()发送name来解决问题,但为什么我必须采取这些额外的步骤?

let names = ['Andy', 'Ross', 'David'];

function printer (name) {
  console.log(name);
}

names.forEach(name => setTimeout(printer.bind(null, name), 1000));

结果:

Andy
Ross
David

5 个答案:

答案 0 :(得分:2)

这是因为执行的顺序。如果将函数调用传递给setTimeout,函数将立即执行,即函数立即放在javascript的执行堆栈上。

如果传递函数名称,即对函数的引用,则只有在计时器完成后,该函数才会被放入javascript线程的执行堆栈中。

答案 1 :(得分:1)

你可以试试这个:

setTimeout(function(){printer(name)}, 1000)

答案 2 :(得分:0)

setTimeout应该将函数作为其第一个参数。

请参阅:

https://www.w3schools.com/jsref/met_win_settimeout.asp

在这里,您将函数的结果作为第一个参数传递,undefined

答案 3 :(得分:0)

你可以这样做:

setTimeout(printer, 1000, name)

答案 4 :(得分:0)

传递函数引用的正确方法是使用回调。

names.forEach(name => setTimeout(function() {
    printer(name);
}, 1000));

回调包含对该函数的引用。

setTimeout(callbackFunction, milliseconds);