在 setTimeout 内调用函数

calling a function within setTimeout

定义函数并调用"callback"

var evenDoubler = function(number, callback) {
    if (number % 2 == 0) {
        setTimeout(function() {
             callback(null, number * 2)
        }, 100);
    }
}

直接调用"callback"

var evenDoubler = function(number, callback) {
    if (number % 2 == 0) {
        setTimeout(callback(null, number * 2), 100);
    }
}

这两种方法有什么区别?

当您 "directly" 调用 callback() 时,会在 计时器关闭之前发生;它发生在调用 setTimeout() 之前。

这样的表达
callback(null, number * 2)

是一个函数调用,因此它总是在 JavaScript 需要它的值时计算。在函数调用中使用时:

setTimeout(callback(null, number * 2), 100);

然后对其求值以获得需要传递给 setTimeout() 的值。这就像用简单的算术表达式调用某个函数一样:

someFunction(x + y);

您完全期望传递给函数的是 xysum。函数调用只是另一种表达式,当它用作函数的参数时,它也会被完全计算。

setTimeout 将函数引用作为第一个参数。因此,当您调用一个函数时(如您的第二种情况),该函数 call 应该 return 一个函数。这不是你的情况。你想传递函数引用——所以不要调用它。您可以使用 bind 来实现,它执行 return 一个新函数,参数已经绑定到它:

var evenDoubler = function(number, callback) {
    if (number % 2 == 0) {
        setTimeout(callback.bind(null, null, number * 2), 100);
    }
}

问题已经得到解答,但我想插话,因为我在学习同一门课程时测试了这个解决方案。

如果你真的想以一种简洁的方式进行 "dirty" 调用,那么将第一个参数作为函数名称,其余参数在超时期限后给出,如下所述:

https://nodejs.org/en/docs/guides/timers-in-node/

按照上面的解释,我用下面的代码测试了代码并起作用了:

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 );
    }
};