所有Node.js回调函数都是异步的吗?

时间:2014-02-19 15:00:19

标签: javascript node.js asynchronous

我正在学习Node.js,我在每个教程中都听到的是“Node is asynchronous and no-blocking!”

我在普通的浏览器JavaScript中听说过只有某些东西,比如AJAX调用可以异步或非阻塞(使用回调)......这也是Node.js的真实情况,或者都是Node.js回调函数是异步/非阻塞的吗?

3 个答案:

答案 0 :(得分:11)

  

所有Node.js回调函数都是异步/非阻塞的吗?

没有。只有I / O通常是异步的,但许多其他回调是同步的。请务必查看文档。

异步函数示例:

  • 异步Filesystem访问权限(虽然没有回调但它们具有同步副本)
  • 计时器(setTimeout
  • process.nextTicksetImmediate
  • 大多数数据库连接
  • 网络连接
  • Promises

同步回调示例:

另见Are all javascript callbacks asynchronous? If not, how do I know which are?(包括其他一些例子)。

答案 1 :(得分:3)

当您将回调传递给函数时,您希望该函数在其他时间调用您的回调函数。但是,它不会自动异步。

假设我有这段代码:

function callSomething(callback) {
  callback();
}

function theCallback() {
  // Do something time consuming here
}

callSomething(theCallback);

在这种情况下,我们传递回调,但回调会立即在现有的调用堆栈上调用。这被认为是不良做法,并且在Node.js中强烈阻止。如果您想立即调用回调,请使用process.nextTick()

function callSomething(callback) {
  process.nextTick(callback);
}

所以对你问题的直接回答大多是肯定的。当您在Node.js中指定函数的回调时,按照惯例,它们将在稍后的时间点在另一个调用堆栈上调用。但是,如果您使用了一些不知道如何遵循此约定的人的错误代码,则无法保证。

答案 2 :(得分:2)

不,它们不会自动异步。请考虑以下代码:

function foo(array, filter, callback) {
    var result = []
    for (var i = 0; i < array.length; i++) {
        if (filter(array[i])) result.push(array[i]);
    }

    callback(result);
}

现在想象一个像这样的程序:

foo([ 1, 2, 3, 4 ], function() { while(true); }, console.log);
console.log('Blocking?');

如果foo是异步的,那么Blocking?会立即出现,但事实并非如此!


但是,您可以非常肯定,进行回调的大多数/所有标准库都是非阻塞异步代码。其中大部分也有Sync对应物。