如何创建自己的setTimeout函数? [英] How to create your own setTimeout function?

查看:93
本文介绍了如何创建自己的setTimeout函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解如何使用 setTimeout 函数,但是找不到找到创建类似函数的方法.
我有一个例子:

I understand how to use setTimeout function, but I can't find a way to create a function like it.
I have an example:

setTimeout(() => {
  console.log('3s');
}, 3000);
while(1);

结果是 setTimeout 回调从不调用,因此我认为它像每个js其他函数一样使用相同的线程.但是,检查时间是否到了?以及如何做到这一点?

The result is setTimeout callback never call so I think it use the same thread like every js other functions. But when it's check the time reach or not? and how it can do that?

为避免引起误解,我更新了我的问题.
我找不到在指定时间后创建带有回调的异步函数的方法(不使用 setTimeout 并且不阻塞整个线程).这个功能 setTimeout 在我看来是一个奇迹.我想了解它的工作原理.

To avoid misunderstanding I update my question.
I can't find a way to create a async function with callback after specify time (without using setTimeout and don't block entire thread). This function setTimeout seen like a miracle to me. I want to understand how it work.

推荐答案

仅用于游戏,因为我真的不明白为什么不能使用setTimeout ...

Just for the game since I really don't see why you couldn't use setTimeout...

要创建一个不阻塞的计时器而不使用setTimeout/setInterval方法,您只有两种方法:

To create a non-blocking timer, without using the setTimeout/setInterval methods, you have only two ways:

  • 基于事件的计时器
  • 在第二个线程中运行无限循环

一个简单的实现是使用 MessageEvent 接口和轮询,直到到达时间为止.但这对于长时间的超时来说并不是真正的建议...

One naive implementation would be to use the MessageEvent interface and polling until the time has been reached. But that's not really advice-able for long timeouts...

function myTimer(cb, ms) {
  var now = performance.now();
  window.addEventListener('message', handleMessage);
  postMessage('myTimer', '*');
  function handleMessage(evt) {
   if(evt.data === 'myTimer') {
      if(performance.now() - now >= ms) {
        window.removeEventListener('message', handleMessage);
        cb();
      }
      else {
        postMessage('myTimer', '*');
      }
    }
  }

}
myTimer(()=>console.log('world'), 2000);
myTimer(()=>console.log('hello'), 200);

因此,如果有的话,可能要使用 Web音频API AudioScheduledSourceNode 大量使用高精度音频上下文自己的时钟:

So instead, if available, one might want to use the Web Audio API and the AudioScheduledSourceNode, which makes great use of the high precision Audio Context's own clock:

function myTimer(cb, ms) {
  if(!myTimer.ctx) myTimer.ctx = new (window.AudioContext || window.webkitAudioContext)();
  var ctx = myTimer.ctx;
  var silence = ctx.createGain();
  silence.gain.value = 0;
  var note = ctx.createOscillator();
  note.connect(silence);
  silence.connect(ctx.destination);
  note.onended = function() { cb() };
  note.start(0);
  note.stop(ctx.currentTime + (ms / 1000));
}

myTimer(()=>console.log('world'), 2000);
myTimer(()=>console.log('hello'), 200);

是的,使用网络工作者,我们可以无限运行循环而不会杀死我们的网页:

Yes, using Web Workers we can run infinite loops without killing our web page:

function myTimer(cb, ms) {
  var workerBlob = new Blob([mytimerworkerscript.textContent], {type: 'application/javascript'});
  var url = URL.createObjectURL(workerBlob);
  var worker = new Worker(url);
  worker.onmessage = function() {
    URL.revokeObjectURL(url);
    worker.terminate();
    cb();
  };
  worker.postMessage(ms);
}

myTimer(()=>console.log('world'), 2000);
myTimer(()=>console.log('hello'), 200);

<script id="mytimerworkerscript" type="application/worker-script">
  self.onmessage = function(evt) {
    var ms = evt.data;
    var now = performance.now();
    while(performance.now() - now < ms) {}
    self.postMessage('done');
  }
</script>

这篇关于如何创建自己的setTimeout函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆