Node.js了解和使用回调-如何和为什么

Node.js了解和使用回调-如何和为什么,node.js,function,asynchronous,callback,Node.js,Function,Asynchronous,Callback,我创建了下面的程序,试图帮助我理解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.cei

我创建了下面的程序,试图帮助我理解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会立即执行
    setTimeout
    中的
    console.log
    语句,而callback-2只在
    setTimeout
    完成时执行该语句,对吗?为了帮助我理解,为什么会这样

  • 在callback-4中,我为
    setTimeout
    语句创建了另一个回调函数。该函数(
    callback\u function
    )有一个参数
    my\u num
    。如果我按照上面显示的方式运行它,那么它将充当回调函数,但当我像这样运行它时
    setTimeout(callback_函数(num),x)然后立即执行-为什么会发生这种情况

  • 这与问题2有关。从
    设置超时(回调函数,x)
    在callback-4中,如何将参数传递给
    callback_函数
    ,就像在
    函数callback_函数(my_num){…
    中定义的那样

  • 据我所知,callback-3在setTimeout中立即执行console.log语句,而callback-2只在setTimeout完成时执行该语句,对吗?为了帮助我理解,为什么会这样做

    这只是一个bug。你永远不会看到像这样的真实代码。它甚至只会执行,因为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_函数)有一个参数my_num。如果我按上面显示的方式运行它,它将充当回调函数,但当我像setTimeout(callback_函数(num),x)那样运行它时,它会立即执行它-为什么会发生这种情况

    因为提供对函数对象的引用与调用函数之间存在差异。在这种情况下,当您真正需要提供对函数的引用时,您正在调用函数。在异步JS中,这种混淆可能会出现在前台,但实际上这是一种基本的JS语言级别你需要花些时间思考的事情,直到你对这一点有100%的清晰


    这与问题2有关。从setTimeout(callback_函数,x);在callback-4中,我如何像在函数callback_函数(my_num){…)中定义的那样将参数传递给callback_函数

    使用包装器函数:

    setTimeout(function () {callback_function(num)})
    
    或者使用Function.bind

    setTimeout(callback_function.bind(null, num))
    

    (这叫做咖喱)。上述两个选项的效果几乎完全相同。Function.bind只是一种方便的语法。

    为了更好地理解node.js,为什么不使用process.nextTick而不是setTimeout?回调函数有点像一个女孩故意把耳环留在你家里,然后她打电话说她就要离开了我是新来的,但我认为你在Q#1中离得太远了。你定义了这个函数,它看到它正在被调用,然后返回并生成一个随机数,直到它到达回调(我的号码)然后执行回调1。查看回调2,获取一个随机数,然后在看到回调(my_number)时点击回调2,依此类推。