请在nextTick文档中解释示例

更新 :这原来是一个非常愚蠢的问题。 在引用的例子中我只是没有注意到一些简单的事情。

我一直在寻找关于刻度和事件循环的信息,而且大多数情况下很明显,但是nextTick文档中有一个例子令我困惑。 它说:

API对于100%同步或100%asynchronous非常重要。 考虑这个例子:

// 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不能保证先被调用? 有一个简单的函数调用(maybeSync),一个if和cb = foo的callback函数。 我认为这条链上的某些东西(可能)是asynchronous的,把事情推到事件队列并继续执行? 我看不出有什么可能有这种效果。

第二个问题:是否有一些文件可以帮助我理解这一点?

这很简单。 如果没有argfoo保证先被调用,如果有argfoo保证被称为“last”。 试想一下这里的调用堆栈:

arg存在

  • maybeSync在相同的事件循环迭代中立即调用cb 。 在相同的事件循环迭代中,也会同步调用foo
  • maybeSync返回 – 所以在这种情况下fs.stat永远不会被调用
  • barfoo完成后被调用

arg不存在

  • maybeSync调用fs.stat (这是asynchronous的)提供cb作为callback
  • 在当前的事件循环迭代中没有更多的同步代码运行,因此调用了bar
  • fs.stat是完整的,它在下一个事件循环迭代中(后面的bar )调用cbfoo同步执行,但这次是在另一个事件循环迭代中执行

两者都很明显。 这里的问题是,在大多数情况下,事先并不知道是否有任何arg值(否则就没有必要),所以你可能有两种运行这个代码的情况,这使得事情变得非常复杂。

process.nextTick在这里模仿fs.statasynchronous特性,所以foo 总是在下一个事件循环迭代中被调用,从而使得stream可预测。