请忽略这样一个事实:这段代码没有任何结果,并为可能是一个无聊的问题道歉!
我理解我不能将函数调用作为第一个参数传递给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
答案 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);