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

时间:2019-03-06 09:25:21

标签: javascript

我想在延迟之后执行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?

3 个答案:

答案 0 :(得分:1)

您可能不需要setTimeout。取而代之的是从promise函数返回test并在then内做其余的事情,这些事情只有在test被解决后才能起作用

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


test().then(function(data) {
  console.log(data)
});

答案 1 :(得分:1)

我想我要提到的是,如果这些test()调用不执行DOM操作,则可以将其移至工作程序。

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

See it in action.

index.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);
};

worker.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);
};

答案 2 :(得分:0)

如果test链中同步消耗的CPU时间超过2000毫秒(“阻塞”),我认为不可能这样-最好的办法是检入{{1} }(或包装在其中的函数中)起始时间(当前为test所在位置)与当前时间之间的时差是否大于2秒-如果是,则执行该函数。例如:

setTimeout

(警告:下面包含上面代码的代码段会阻塞浏览器一段时间,具体取决于您的硬件)

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');花费的时间太长,并且超时不够准确(例如,如果测试花费400毫秒,而花费的时间则从1800毫秒变为2200毫秒,并且200毫秒的误差太大) ,则必须更改test代码,以便在其中进行多次检查。

相关问题