Node.js:异步回调 vs 同步回调 vs process.nextTick vs setTimeout

wiz*_*ard 3 javascript asynchronous callback node.js

不久前我开始使用node.js进行开发。最近,我深入 研究了节点的“事件循环”和异步机制。但我仍然不完全理解同步和异步回调之间的区别。

在这个来自node.js API的示例中,我理解为什么不清楚首先调用哪个函数。

maybeSync(true, () => {
  foo();
});
bar();
Run Code Online (Sandbox Code Playgroud)

但是,如果我们有:

syncOrAsync(arg, () => {
 if (arg) {
   cb(arg);
   return;
 }
});

syncOrAsync(true, function(result) {
  console.log('result');
});

console.log('after result);
Run Code Online (Sandbox Code Playgroud)

我不清楚为什么它们总是按同步顺序执行,尽管我做了一个回调函数,该函数应该在堆栈为空由事件循环执行( console.log('after result') 完成)。我是否总是需要添加 process.nextTick(cb);才能实现异步?process.nextTick 和 process.nextTick 之间有什么区别setTimeout();

ade*_*neo 5

除非你有一些实际上是异步的东西,比如计时器或外部调用等,否则代码将始终是同步的,因为这是所有 javascript 代码的默认状态。
添加回调不会使其异步

这是异步代码的示例

function syncOrAsync(sync, cb) {
    if (sync) {
        return cb();
    } else {
        setTimeout(cb, 100); // async, waits 0.1 seconds to call callback
    }
}

syncOrAsync(true, function(result) { // synchronous call
    console.log('result 1'); // happens first
});

syncOrAsync(false, function(result) { // asynchronous call
    console.log('result 2'); // happens last, as it's async
});


console.log('result 3');     // happens second
Run Code Online (Sandbox Code Playgroud)


使用process.nextTick()并没有真正使函数异步,但它确实做了一些相同的事情

function syncOrAsync() {
    console.log('result 1'); // this happens last
}

process.nextTick(syncOrAsync);

console.log('result 2'); // this happens first
Run Code Online (Sandbox Code Playgroud)

这会将 的执行推迟syncOrAsync到事件循环的下一次传递,因此它在很多方面与 相同setTimeout(syncOrAsync),但该函数仍然不会是异步的,回调将立即执行,我们只是延迟了整个执行的函数。

  • 是的,Javascript 是同步且单线程的,一切都按照编写的顺序发生。异步代码大多数时候依赖于内置的异步函数,在浏览器中是 ajax、计时器等,在 Node 中是对操作系统的调用、数据库查找等。 (2认同)