如何在延迟后立即执行设置超时函数?



我想在延迟后执行 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 秒后而不是最后获得设置超时?

我想我会提到,如果这些test()调用不执行DOM操作,你可以将它们移动到worker。

Web 辅助角色允许在不阻止主 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);
};

你可能不需要setTimeout.而是从函数返回testpromise,并在then内执行其余操作,这些操作仅在解决test后才能工作

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

如果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代码,以便它在内部进行多次检查。

最新更新