Javascript 在setTimeout内调用函数
定义函数并调用“回调” 直接调用“回调” 这两种方法有什么区别 当您“直接”调用Javascript 在setTimeout内调用函数,javascript,node.js,event-loop,Javascript,Node.js,Event Loop,定义函数并调用“回调” 直接调用“回调” 这两种方法有什么区别 当您“直接”调用callback()时,这发生在计时器关闭之前;它发生在调用setTimeout()之前 像这样的表情 callback(null, number * 2) 是一个函数调用,因此它总是在JavaScript需要其值时进行计算。在函数调用中使用时: setTimeout(callback(null, number * 2), 100); 然后对其求值,以获得需要传递给setTimeout()的值。这与使用简单的算术
callback()
时,这发生在计时器关闭之前;它发生在调用setTimeout()
之前
像这样的表情
callback(null, number * 2)
是一个函数调用,因此它总是在JavaScript需要其值时进行计算。在函数调用中使用时:
setTimeout(callback(null, number * 2), 100);
然后对其求值,以获得需要传递给setTimeout()
的值。这与使用简单的算术表达式调用某个函数相同:
someFunction(x + y);
您完全希望传递给函数的是x
和y
之和。函数调用只是另一种表达式,当它用作函数的参数时,它也将被完全计算。当您“直接”调用回调()
时,这发生在计时器关闭之前;它发生在调用setTimeout()
之前
像这样的表情
callback(null, number * 2)
是一个函数调用,因此它总是在JavaScript需要其值时进行计算。在函数调用中使用时:
setTimeout(callback(null, number * 2), 100);
然后对其求值,以获得需要传递给setTimeout()
的值。这与使用简单的算术表达式调用某个函数相同:
someFunction(x + y);
您完全希望传递给函数的是
x
和y
之和。函数调用只是另一种表达式,当它用作函数的参数时,也会对其进行完全计算。setTimeout
将函数引用作为第一个参数。因此,当您调用函数时(如第二种情况),该函数调用应该返回一个函数。这不是你的情况。您希望传递函数引用,所以不要调用它。您可以使用bind
执行此操作,它会返回一个新函数,并且参数已绑定到该函数:
var evenDoubler = function(number, callback) {
if (number % 2 == 0) {
setTimeout(callback.bind(null, null, number * 2), 100);
}
}
setTimeout
将函数引用作为第一个参数。因此,当您调用函数时(如第二种情况),该函数调用应该返回一个函数。这不是你的情况。您希望传递函数引用,所以不要调用它。您可以使用bind
执行此操作,它会返回一个新函数,并且参数已绑定到该函数:
var evenDoubler = function(number, callback) {
if (number % 2 == 0) {
setTimeout(callback.bind(null, null, number * 2), 100);
}
}
问题已经回答了,但我想插话,因为我在学习同一课程时已经测试了这个解决方案 如果您确实希望以简洁的方式执行“dirty”调用,则只需将第一个参数作为函数名,其余参数在超时后,如下所述: 按照上面的解释,我用下面的代码进行了测试,结果如下:
var eventDoubler = function (num, callback) {
var waitTime = Math.floor(Math.random()*(maxTime+1));
if( num % 2 ) {
setTimeout(callback, waitTime, new Error('Odd Input'));
} else {
setTimeout(callback, waitTime, null, num*2 , waitTime );
}
};
问题已经回答了,但我想插话,因为我在学习同一课程时已经测试了这个解决方案 如果您确实希望以简洁的方式执行“dirty”调用,则只需将第一个参数作为函数名,其余参数在超时后,如下所述: 按照上面的解释,我用下面的代码进行了测试,结果如下:
var eventDoubler = function (num, callback) {
var waitTime = Math.floor(Math.random()*(maxTime+1));
if( num % 2 ) {
setTimeout(callback, waitTime, new Error('Odd Input'));
} else {
setTimeout(callback, waitTime, null, num*2 , waitTime );
}
};
不同之处在于,第二个代码段并不像您预期的那样工作。@Teemu从技术上讲是工作的,但不是超时应该运行的方式@OP
setTimeout
需要一个函数作为参数。通过运行setTimeout(回调(null,数字*2),100)
,您的意思是回调的返回是参数。它立即执行。这就是为什么在第一个示例中,您使用了一个匿名函数作为参数。@SterlingArcher是的,我已经尝试澄清了注释。参数被急切地求值(可能还有另一个术语,但我不记得了)。这意味着foo(bar())
将始终首先调用bar
,并将返回值传递给foo
。不同之处在于第二个代码段并不像您预期的那样工作。@Teemu从技术上讲是工作的,但不是超时应该运行的方式@OPsetTimeout
需要一个函数作为参数。通过运行setTimeout(回调(null,数字*2),100)
,您的意思是回调的返回是参数。它立即执行。这就是为什么在第一个示例中,您使用了一个匿名函数作为参数。@SterlingArcher是的,我已经尝试澄清了注释。参数被急切地求值(可能还有另一个术语,但我不记得了)。这意味着foo(bar())
将始终首先调用bar
,并将返回值传递给foo
。