我正在学习Node.js,我在每个教程中听到的都是“Node is asynchronous and no-blocking!”所有的Node.js回调函数都是异步的吗?
我听说过在常规的浏览器JavaScript中,只有某些东西,如AJAX调用可以是异步或非阻塞的(使用回调)...... Node.js也是如此,或者都是Node.js回调函数使异步/非阻塞?
我正在学习Node.js,我在每个教程中听到的都是“Node is asynchronous and no-blocking!”所有的Node.js回调函数都是异步的吗?
我听说过在常规的浏览器JavaScript中,只有某些东西,如AJAX调用可以是异步或非阻塞的(使用回调)...... Node.js也是如此,或者都是Node.js回调函数使异步/非阻塞?
不,它们不会自动异步。考虑以下代码:
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
副本。
当您将回调传递给某个函数时,您期望该函数可以在其他时间调用您的回调函数。但是,它不会自动异步。
假设我有这样的代码:
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中为函数指定回调时,按照惯例,它们将在稍后的时间点在另一个调用堆栈上被调用。但是如果你使用了一些不知道如何遵循这个约定的不好的代码,那么这是不能保证的。
一般而言。另外值得一提的是,可以使用'setImmediate',我听说过几个节点核心成员说使用它比'nextTick'更好,以避免'nextTick'特定的问题(主要是IO饥饿) – vkurchatkin
@vkurchatkin有趣的是,我没有没听说过setImmediate。我绝对会在我的一些项目中交换这个! http://stackoverflow.com/a/15349865/362536 – Brad
是否所有的Node.js回调函数都是异步/非阻塞的?
不。只有I/O通常是异步的,但许多其他回调是同步的。总是检查文档。的异步函数
实例:
setTimeout
)process.nextTick
,setImmediate
forEach
sort
比较回调replace
匹配回调实例
另请参阅Are all javascript callbacks asynchronous? If not, how do I know which are?(包括一些其他示例)。
这不完全准确。你是对的,I/O是多线程的,其余的都不是,但许多其他的回调仍然是异步的,并在一个单独的调用堆栈中调用。 – Brad
你是指什么其他回调? – vkurchatkin
当您将函数作为参数传递时,并不意味着它是回调。 ForEach是迭代器,EventEmitter是监听器 – vkurchatkin
是的。这是javascript的本质,不是node.js的具体情况。 – zsong
@zsong这并不完全准确。 – Brad
这是完全不准确的。阅读规格。没有关于同步/异步或阻塞/非阻塞或io – vkurchatkin