在 JavaScript 中编写非阻塞 for 循环最简洁的方法是什么?
所以,我一直在考虑一个脑筋急转弯 - 如果我有一个大对象,由于某种原因我必须在 Node js 中进行迭代,并且不想在这样做时阻止事件循环,该怎么办?
这是一个我脑海中浮现的例子,我确信它可以更清晰:
var forin = function(obj,callback){
var keys = Object.keys(obj),
index = 0,
interval = setInterval(function(){
if(index < keys.length){
callback(keys[index],obj[keys[index]],obj);
} else {
clearInterval(interval);
}
index ++;
},0);
}
虽然我确信还有其他原因导致它混乱,但这将比常规 for 循环执行得更慢,因为setInterval 0 实际上并不是每 0 毫秒执行一次,但我不确定如何使用更快的 process.nextTick 进行循环。
在我的测试中,我发现这个示例需要 7 毫秒才能运行,而本机 for 循环(使用 hasOwnProperty() 检查,记录相同的信息)则需要 4 毫秒。
那么,使用 Node.js 编写相同代码的最干净/最快的方法是什么?
So, I've been thinking about a brain teaser - what if I had a large object I for some reason had to iterate through in node js, and didn't want to block the event loop while I was doing that?
Here's an off-the-top-of-my-head example, I'm sure it can be much cleaner:
var forin = function(obj,callback){
var keys = Object.keys(obj),
index = 0,
interval = setInterval(function(){
if(index < keys.length){
callback(keys[index],obj[keys[index]],obj);
} else {
clearInterval(interval);
}
index ++;
},0);
}
While I'm sure there are other reasons for it being messy, this will execute slower than a regular for loop, because setInterval 0 doesn't actually execute every 0 ms, but I'm not sure how to make a loop with the much faster process.nextTick.
In my tests, I found this example takes 7 ms to run, as opposed to a native for loop (with hasOwnProperty() checks, logging the same info), which takes 4 ms.
So, what's the cleanest/fastest way to write this same code using node.js?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
自提出问题以来,
process.nextTick
的行为已发生变化。之前的答案也没有按照功能的简洁性和效率来遵循问题。请注意关于 Kue 和正确作业队列的 @alessioalex 的评论。
另请参阅:share-time,我编写的一个模块,用于执行类似于原来的问题。
The behavior of
process.nextTick
has changed since the question was asked. The previous answers also did not follow the question as per the cleanliness and efficiency of the function.Do take note of @alessioalex's comments regarding Kue and proper job queueing.
See also: share-time, a module I wrote to do something similar to the intent of the original question.
这里有很多话要说。
a)将“for in”循环放入子进程中,并在结束后在主应用程序中获取结果
b) 如果你想实现延迟工作(例如发送电子邮件)之类的目标,你应该尝试 https://github。 com/LearnBoost/kue
c) 使用 Redis 创建一个类似 Kue 的程序,在主应用程序和“繁重”应用程序之间进行通信。
对于这些方法,您还可以使用多个进程(用于并发)。
现在是示例代码了(它可能并不完美,所以如果您有更好的建议请纠正我):
There are many things to be said here.
a) put your "for in" loop in a child process and get the result in your main app once it's over
b) if you are trying to achieve something like delayed jobs (for ex sending emails) you should try https://github.com/LearnBoost/kue
c) make a Kue-like program of your own using Redis to communicate between the main app and the "heavy lifting" app.
For these approaches you could also use multiple processes (for concurrency).
Now time for a sample code (it may not be perfect, so if you have a better suggestion please correct me):
而不是:
做这样的事情:
这将运行 100 次循环迭代,然后将控制权暂时返回给系统,然后从中断处继续,直到完成。
编辑:这里它适合您的特定情况(并且它一次执行的迭代次数作为参数传入):
Instead of:
do something like this:
This will run 100 iterations of the loop, then return control to the system for a moment, then pick up where it left off, till its done.
Edit: here it is adapted for your particular case (and with the number of iterations it performs at a time passed in as an argument):
以下内容适用于[浏览器] JavaScript;它可能与 Node.js 完全无关。
我知道的两个选项:
我不确定 Web Workers 是否适用/可用。
快乐编码。
The following applies to [browser] JavaScript; it may be entirely irrelevant to node.js.
Two options I know of:
I am not sure if Web Workers are applicable/available.
Happy coding.