我想为要执行的功能设置一个限制时间,如果它当时无法完成其工作,则应该中止该功能的执行。我必须用什么方式处理它。我以为我会在运行时为每个函数创建一个“ setTimeout”,但我想不出一种方法来中止函数的执行,除非它位于“ setTimeout”中,而我可以给它“ cleanTimeout”并中止,但是可以想到其他方法吗?
示例
超时:
const eventBus = new EventEmitter();
function Timeout(parent) {
this.id = undefined;
this.parent = parent;
}
Timeout.prototype.set = function(limitTimeMs) {
const parent = this.parent;
this.id = setTimeout(function() {
eventBus.emit('runEnd', parent);
}, limitTimeMs);
}
Timeout.prototype.clear = function() {
clearTimeout(this.id);
}
亚军:
function Runner() {
this.tests = [];
eventBus.on('runEnd', function(test) {
console.log('runEnd');
// results ready for the preview layer...
});
eventBus.on('testEnd', function(test) {
console.log('testEnd');
});
}
Runner.prototype.addTest = function(test) {
this.tests.push(test);
}
Runner.prototype.run = function() {
for(let i = 0; i < this.tests.length; i++)
this.tests[i].run();
}
测试:
function Test(fn, limit) {
this.fn = fn;
this.limit = limit;
this.timeout = new Timeout(this);
}
Test.prototype.run = function() {
this.fn.call(this);
this.timeout.clear();
eventBus.emit('testEnd', this);
}
主要:
const runner = new Runner();
const test1 = new Test(function() {
this.timeout.set(1);
let i = 0;
while(i < 1000000000)
i++;
});
runner.addTest(test1);
runner.run();
实际示例:
http://playcode.io/197465?tabs=console&script.js&output
我已经简化了最大值,我还必须处理异步的“测试”。问题是我最多可以配置“ this.timeout.set(0);”。仍然是“ fn();”首先执行,即使在上面的“ while”中花了很长时间,还是“ this.timeout.set(0);”在它之后运行。我知道要调用“ setTimeout”有一个最小值,即“ 4ms”(取决于浏览器),我必须能够处理什么替代方案?请注意,我无法修改“ fn”功能,只能在其之前或之后添加代码。
我意识到我试图做的事情对于单个线程来说是荒谬的,如果立即执行“ setTimout(0)”,那当然可以奏效,但是仍然存在测试函数将继续执行它的问题执行,这是处理问题的非常难看的方法。我发现了另一种方法,因为我想避免“ stackoverflow”错误,因此我根据Web Worker的 @blex 示例进行了此操作,它可以正常工作,但是后来我想,为什么我应该这样做?想避免“ stackoverflow”?那不是很糟糕吗?如何知道它是否会导致错误,这可能会令人困惑,但是我仍然继续,因为我需要知道我是否可以这样做,在这里就可以了:
http://playcode.io/198133?tabs=console&index.html&output
但是我想更好,我不想避免“堆栈超出”错误,如果发生,最好让我知道。因此,我将以其他方式处理,这比较简单,我将选择初始时间,然后是测试结束时的时间,将持续时间与超时进行比较,如果超过了超时时间,那么我会出错。我不再认为该问题是问题,该函数将执行到最后以检查时间是否已到,从而无法避免出现“堆栈超出”错误。
答案 0 :(得分:0)
您可以使用生成器在两者之间产生执行,然后检查时间是否结束:
function runMax(fn, max) {
const endAt = Date.now() + max;
let done, iterator = fn();
do {
({ done } = iterator.next());
if(Date.now() >= endAt) return;
} while(!done)
}
console.log("start");
runMax(function* () {
while(true) {
// some long running code
console.log("do stuff");
// sometimes yield inbetween:
yield;
}
}, 1000);
console.log("aborted");