【问题标题】:Node.js understading and using callbacks - how and whyNode.js 理解和使用回调——如何以及为什么
【发布时间】:2013-08-31 19:33:57
【问题描述】:

我创建了以下程序来尝试帮助我理解 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

我的问题是:

  1. 据我了解,callback-3 立即执行 setTimeout 内的 console.log 语句,而 callback-2 仅当setTimeout 完成时执行它 - 正确吗?为了帮助我理解,为什么会这样?

  2. callback-4 中,我为 setTimeout 语句创建了另一个回调函数。该函数 (callback_function) 有一个参数 my_num。如果我按照上面显示的方式运行它,它就会充当回调,但是当我像 setTimeout(callback_function(num), x); 这样运行它时,它会立即执行它 - 为什么会发生这种情况?

  3. 这与问题 2 相关。从 callback-4 中的 setTimeout(callback_function, x);,我如何将参数传入 callback_function,就像它在function callback_function(my_num) {... ?

【问题讨论】:

  • 为了更好地理解node.js,为什么不用process.nextTick来代替setTimeout呢?
  • 回调函数有点像当一个女孩故意把她的耳环留在你家门外,然后她打电话说她只是要去捡起来,但一直等到你把她叫出来.我是新手,但我认为您在 Q#1 中还有很长的路要走。您定义该函数,它看到它被调用然后运行并生成一个随机数,直到它到达回调(my_number)然后执行回调 1。看到回调 2,获取一个随机数,然后在看到回调时向上回调 2 (my_number) 等等。

标签: node.js function asynchronous callback


【解决方案1】:

据我了解,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(my_num) {... 中定义的那样向 callback_function 传递一个参数?

要么使用包装函数:

setTimeout(function () {callback_function(num)})

或使用 Function.bind

setTimeout(callback_function.bind(null, num))

(这称为柯里化)。上述两个选项都实现了几乎完全相同的目标。 Function.bind 只是一种方便的语法。

【讨论】:

    猜你喜欢
    • 2011-08-02
    • 2014-04-23
    • 2020-01-20
    • 2018-12-21
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多