10

我正在开发一个 JavaScript 库,该库除其他外提供可异步迭代的序列上的 map/reduce 函数。

GitHub 上一位乐于助人的人建议,对于 Node.js,我应该使用它process.nextTick来尽可能快地进行异步迭代。(该库目前setTimeout在所有环境中都使用,我确实知道这是次优的。)我对 Node 非常缺乏经验,所以我正在阅读这种方法的工作原理,我不清楚它是否是一个好的选择与否。

根据对 SO 上另一个问题的回答,似乎setImmediate在这种情况下使用它可能更有意义,因为它nextTick显然会跳到未决的 I/O 事件之前,这对我来说似乎很糟糕。

Node v0.10.0 官方公告中的一些言论似乎证实了这一点:

在 v0.10 中,nextTick处理程序在每次从 C++ 调用 JavaScript 后立即运行。这意味着,如果您的 JavaScript 代码调用 process.nextTick,则回调将在代码运行完成后立即触发,但返回事件循环之前。

所以我是对的,异步迭代序列应该用setImmediate? 或者nextTick在这里会是更好的选择?(在任何一种情况下,一个清楚的解释为什么会非常感激。)

4

1 回答 1

10

一些考虑:

我会首先对扩展 setImmediate 比process.nextTick. 如果它不是(很多)慢,我会setImmediate马上去,因为这不会饿死事件循环。

在节点 0.10 中,您可以递归调用 nextTick 的次数有一个硬性限制(1000,请参见node.js 文档),因此在任何情况下都应该防止这种情况发生。您要么需要在迭代之前选择策略,要么能够在迭代期间更改策略(同时检查当前迭代计数)。

如果您出于性能原因选择 process.nextTick,您可能希望设置一个可配置的硬限制,用于连续执行多少次process.nextTick,否则切换到setImmediate. 我没有在 nodejs 上进行严重工作负载的经验,但我认为如果你的库使他们的 I/O 不稳定,人们不会喜欢它。

总而言之,setImmediate 肯定是最安全的。

至于浏览器:我还没有研究过你的库,但由于你实际上来自setTimeout,你可能会通过什么来帮助你了解新的延迟技术window.postMessage。有一个不错的小型库,称为next-tick(但与节点 next-tick 的语义不同!),并且有一个用于 setImmediate 的跨浏览器填充程序,它相当重,因为 1)它需要实现 setImmediate 规范(包括取消计划任务的能力)和2)它具有更广泛的浏览器兼容性。

查看此异步排序演示,将 setImmediate (shim) 与 setTimeout 进行比较。

于 2013-05-20T23:19:29.067 回答