更新:结果证明这是一个非常愚蠢的问题。我在引用的例子中没有注意到一些简单的事情。
我一直在查看关于刻度线和事件循环的信息,而且大部分情况都很清楚,但the nextTick documentation中的一个例子令我感到困惑。它说:
API非常重要,无论是100%同步还是100% 异步。考虑这个例子:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD! function maybeSync(arg, cb) { if (arg) { cb(); return; } fs.stat('file', cb); }
此API有害。如果你这样做:
maybeSync(true, function() { foo(); }); bar();
然后不清楚是先调用foo()还是bar()。
第一个问题:为什么 foo不能保证先被调用?有一个简单的函数调用(maySync),一个 if ,以及一个cb = foo的回调。我认为这个链中的某些东西(可能)是异步的,将某些内容推送到事件队列并继续执行?我不知道有什么可能产生这种影响。
第二个问题:是否有某些文件可以让我自己理解这个?
答案 0 :(得分:1)
这非常简单。如果没有foo
,则保证arg
首先被调用,如果有foo
,则保证arg
被称为“最后”。想象一下调用堆栈:
arg
存在
cb
。 foo
也在同一事件循环迭代中同步调用fs.stat
bar
在foo
完成后调用
arg
不存在
fs.stat
(这是异步的)提供cb
作为回调bar
fs.stat
已完成,并在下一次事件循环迭代(cb
之后)上调用bar
。 foo
同步执行,但这次是在另一个事件循环迭代中执行两者都很明显。这里的问题是,在大多数情况下,你事先不知道是否有任何arg
值(否则if
:)中没有必要)所以你可以有两个运行这个代码的场景事情很复杂。
process.nextTick
在此处模仿fs.stat
的异步性质,以便在下一个事件循环迭代中调用foo
始终,从而使流量可预测。