繁体   English   中英

延迟后如何立即执行setTimeout函数?

[英]How to execute setTimeout function immediately after the delay?

我想在延迟之后执行 setTimeout 而不是在所有其他函数都执行后等待它从消息队列中调用。 请参考以下代码:

let test = function(){ console.log('test') }
setTimeout(() => console.log('hi'), 2000)

test();
test();
test();
.
.
.
.
this code takes more than 2 seconds to execute;

如何在 2 秒后而不是在最后获得 setTimeout ?

您可能不需要setTimeout 而是从test函数返回一个promisethen在里面做其余的事情,只有在test解决后才能工作

 let test = function() { return new Promise(function(resolve, reject) { console.log('test'); resolve('test executed') }) } test().then(function(data) { console.log(data) });

我想我会提到,如果那些test()调用不执行 DOM 操作,您可能会将它们移至工作人员。

Web Workers允许在不阻塞主 UI 线程的后台线程上运行代码。 我创建了一个快速示例,它在工作线程上运行任意持续时间的同步任务。 在主线程上, setIntervalsetTimeout调用不间断地运行。

看到它在行动。

索引.js

let interval = setInterval(() => console.log("Not blocked"), 500);

console.log("Scheduling to run in 2 seconds");
setTimeout(() => {
  console.log("2 seconds passed. Running scheduled task! ");
}, 2000);

let longTaskRunner = new Worker("./src/worker.js");
let taskDuration = 3;
console.log(
  `Starting synchronous task that takes more than ${taskDuration} seconds`
);

longTaskRunner.postMessage(taskDuration);
longTaskRunner.onmessage = function(e) {
  console.log(`Long task completed in ${e.data} seconds`);
  clearInterval(interval);
};
longTaskRunner.onerror = function(e) {
  console.log(e.message);
};

工人.js

self.onmessage = function(e) {
  const runFor = e.data * 1000;
  let startedAt = Date.now();
  let timeElapsed = 0;

  while (timeElapsed < runFor) {
    timeElapsed = Date.now() - startedAt;
  }

  self.postMessage(timeElapsed / 1000);
};

如果test链同步消耗超过 2000 毫秒的 CPU 时间(“阻塞”),我认为这是不可能的 - 你能做的最好的事情是检查test (或在它周围的函数中)是否开始(您的setTimeout当前所在的位置)与当前时间之间的时间差超过 2 秒 - 如果是,请执行该函数。 例如:

console.log('start');
let hasRun = false;
const fnToRunLater = () => console.log('hi');
const startTime = Date.now();
function test() {
  const now = Date.now();
  if (!hasRun && now - startTime > 2000) {
    fnToRunLater();
    hasRun = true;
  }
  for (let i = 0; i < 2e8; i++) {
    // some expensive operations
  }
}
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
if (!hasRun) {
  fnToRunLater();
}
console.log('done');

(警告:下面包含上述代码的代码段将阻止您的浏览器,具体取决于您的硬件)

 // look at the timing in your browser console, not the snippet console console.log('start'); let hasRun = false; const fnToRunLater = () => console.log('hi'); const startTime = Date.now(); function test() { const now = Date.now(); if (!hasRun && now - startTime > 2000) { fnToRunLater(); hasRun = true; } for (let i = 0; i < 2e8; i++) { // some expensive operations } } test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); if (!hasRun) { fnToRunLater(); } console.log('done');

如果单个test花费的时间太长,并且超时不够准确(例如,如果测试花费 400 毫秒,这需要从 1800 毫秒到 2200 毫秒的差异,那么 200 毫秒的不准确度太多了),那么您将不得不更改test代码,使其在内部进行多项检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM