我已经创建了以下程序来尝试帮助我理解node.js中的异步调用/回调,但结果却出现了更多问题。
var z = 0
// define our function with the callback argument
function some_function(arg1, arg2, callback) {
// this generates a random number between
// arg1 and arg2
var my_number = Math.ceil(Math.random() *
(arg1 - arg2) + arg2);
// then we're done, so we'll call the callback and
// pass our result
callback(my_number);
}
// call the function - callback 1
some_function(5, 15, function(num) {
// this anonymous function will run when the
// callback is called
z = 1;
console.log("callback 1 called! " + num + " z= " + z);
});
// call the function - callback 2
some_function(20, 25, function(num) {
// this anonymous function will run when the
// callback is called
var x=3000;
z = 2;
setTimeout(function() {
console.log("callback 2 called! " + num + "-> but waited " + x + " z= " + z);
}
,x);
});
// call the function - callback 3
some_function(30, 35, function(num) {
// this anonymous function will run when the
// callback is called
var x=5000;
z = 3;
setTimeout(console.log("callback 3 called! " + num + "-> but waited " + x + " z= " + z), x);
});
//callback function for callback 4
function callback_function(my_num) {
z = 4;
console.log("callback 4 called! " + "-> but waited " + " z= " + z);
}
// call the function - callback 4
some_function(40, 45, function(num) {
// this anonymous function will run when the
// callback is called
var x=6000;
setTimeout(callback_function, x);
});
这是我得到的输出:
node callback_test.js
callback 1 called! 13 z= 1
callback 3 called! 35-> but waited 5000 z= 3
callback 4 called! -> but waited z= 4
callback 2 called! 25-> but waited 3000 z= 4
我的问题是:
根据我的理解, callback-3 立即在console.log
内执行setTimeout
语句,而不是 callback-2 只在setTimeout
完成时才执行它 - 这是正确的吗?为了帮助我理解,为什么呢?
在 callback-4 中,我为setTimeout
语句创建了另一个回调函数。该函数(callback_function
)具有参数my_num
。如果我按上面显示的那样运行它,那么它就作为一个回调,但当我像setTimeout(callback_function(num), x);
那样运行它然后立即执行它 - 为什么会发生这种情况?
这与问题2有关。来自 callback-4 中的setTimeout(callback_function, x);
,如何将参数传递给callback_function
,就像它有已在function callback_function(my_num) {...
中定义?
答案 0 :(得分:0)
据我所知,callback-3立即执行setTimeout中的console.log语句,而不是callback-2,它只在setTimeout完成时执行 - 这是正确的吗?为了帮助我理解,为什么呢?
这只是一个错误。你永远不会看到像这样的真实代码。它甚至只是执行,因为JavaScript对类型非常宽松。
setTimeout(console.log("callback 3 called! " + num + "-> but waited " + x + " z= " + z), x);
console.log语句立即执行并计算为undefined
,因此这相当于调用setTimeout(undefined)
,因为setTimeout
期望函数和可选的延迟作为其参数,它不会'做任何事。 setTimeout在这里抛出一个异常可能更安全,但在这种情况下,JavaScript只会继续并忽略非函数参数。
在callback-4中,我为setTimeout语句创建了另一个回调函数。该函数(callback_function)有一个参数my_num。如果我按上面显示的那样运行它,那么它就作为一个回调但是当我像这个setTimeout(callback_function(num),x)那样运行它时;然后它立即执行 - 为什么会发生这种情况?
因为为函数对象提供引用和调用函数之间存在差异。在这种情况下,当您真正需要提供对它的引用时,您正在调用该函数。这种混淆可以在异步JS中引入前台,但实际上它是一个基本的JS语言级别的东西,你需要花一些时间思考,直到你在这一点上100%清晰。
这与问题2有关。来自setTimeout(callback_function,x);在callback-4中,如何将参数传递给callback_function,就像在函数callback_function(my_num)中定义的那样{...?
使用包装函数:
setTimeout(function () {callback_function(num)})
或使用Function.bind
setTimeout(callback_function.bind(null, num))
(这称为currying)。上述两个选项几乎完全相同。 Function.bind只是一种方便的语法。