首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >node.js setTimeout分辨率非常低且不稳定

node.js setTimeout分辨率非常低且不稳定
EN

Stack Overflow用户
提问于 2013-08-19 23:37:28
回答 3查看 3K关注 0票数 4

我有一个关于setTimeout解析的问题。当我将其设置为50毫秒时,它从51毫秒到80毫秒不等。当我使用休眠模块时,我能够获得类似50µs的分辨率,那么setTimeout函数的问题是什么,以获得至少1ms的分辨率?有什么办法可以解决/避免这个问题吗?睡眠的问题是,它会延迟一切,即使回调函数应该被触发,它也会等待……有没有另一种解决方案来拍摄一些事件的延迟恰好是50ms?

例如,使用睡眠模块:

代码语言:javascript
运行
复制
var start = new Date().getTime();
sleep.usleep(50);
console.log(new Date().getTime() - start);`

结果是: 0。而microtime显示它是51到57微秒。那么见鬼,那又如何?

EN

回答 3

Stack Overflow用户

发布于 2013-08-19 23:46:46

setTimeout docs

需要注意的是,您的回调可能不会在精确的延迟毫秒内被调用

延迟的精确度取决于代码阻塞的程度,这意味着如果您在代码所具有的单个线程上执行大量操作,则setTimeout可能会因大量延迟而被触发。相反,它几乎是准确的。

您可以自己看到不同之处,执行以下命令

代码语言:javascript
运行
复制
var start = Date.now();
setTimeout(function() { console.log(Date.now() - start); }, 500);
for(var i=0; i<999999999; ++i){}

// 1237ms

注意这一点的区别:

代码语言:javascript
运行
复制
var start = Date.now();
setTimeout(function() { console.log(Date.now() - start); }, 500);

// 507ms
票数 2
EN

Stack Overflow用户

发布于 2013-08-19 23:51:15

因此,为了获得像setTimeout这样的最佳时间速率,我们希望使给定模块的事件循环尽可能小。这最大限度地减少了V8引擎为循环做工作所花费的时间。最好的情况:

代码语言:javascript
运行
复制
setInterval(function(){}, 50);

如果这是文件中的唯一内容,则精度将非常高,因为没有发生任何其他事情。因此,我们所做的是,我们为一个特定的模块派生一个进程,该模块只执行我们希望在此时间间隔内完成的工作。如果函数中唯一的东西是异步请求,那么它就和上面的一样好。因此,我们在setInterval函数上获得了非常高的精度。

在一个文件中,我们需要以下内容,我们将其命名为file1.js。

代码语言:javascript
运行
复制
var http = require('http');

var options = {
    hostname: 'localhost',
    port: 8888,
    path:'/',
    method: 'GET'
}

setInterval(function(){
    console.log('File:' + (new Date).getTime() % 50);
    //The Modulus of the time in MS should change by no more than 1 MS on consecutive runs, I confirmed this works just dandy on my system(though the first couple intervals were slower in some instances, worse I saw was a 3 MS delay)
    var req = http.request(options, function (res) {
        res.on('data', function (data) {
            console.log(data.toString());
        });
    });

    req.end();
}, 50);

在第二个文件中,我们可以做更多的工作,实际上是我们想做的任何工作。重要的是,我们生成了一个进程来完成上述工作,并包含在它自己的进程中。这允许进程V8处理器将此事件循环保持得非常小。我们仍然是CPU上给定进程的操作系统管理的受害者,但我们仍然可以期望我们的file1.js模块每毫秒至少引起一次关注,因为它所做的一切都是异步调用,然后查找下一次它需要启动的异步调用,我们在调用之间得到的最大延迟是1ms(至少我在我的系统上看到的就是这样)。因此,另一个文件可以包含任意数量的工作,并且有一行非常重要:

file2.js:

代码语言:javascript
运行
复制
var http = require('http');
var child_process = require('child_process');


http.createServer(function (req, res) {
    res.write('Hi There');
    res.end();
}).listen(8888);

///Do whatever else you need to do

child_process.fork('file1.js');//Add in this line!!!!

预期输出:

代码语言:javascript
运行
复制
File:29
Hi There
File:29
Hi There
File:30//Notice these values only increase by 0 or 1.  
Hi There
File:31
Hi There
File:31
Hi There
File:32
Hi There
File:34//Uh oh, one went up by 2... not terrible
Hi There
File:35
Hi There
File:35
票数 0
EN

Stack Overflow用户

发布于 2017-05-25 16:26:25

是的,我希望它能更精确,这样我有趣的waitSort就可以工作了:)

但是,它可以在这里工作,但不能在节点中工作

代码语言:javascript
运行
复制
const posInts = [5,2,7,9,4,6,1,3]

const waitSort = arr => new Promise(done => {
  const ret = []
  const last = Math.max(...arr)
  arr.forEach(i => {
    setTimeout(() => {
      ret.push(i)
      if(i === last){
        done(ret)
      }
    }, i)
  })
})

waitSort(posInts).then(console.log)
console.log(posInts)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18317717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档