sra*_*ara 11 javascript timeout
如何在Javascript中实现超时,而不是window.timeout像session timeout或者socket timeout- 基本上 - 一个" function timeout"
除非先发生另一个指定事件,否则将在指定事件发生之前允许在系统中经过的指定时间段; 在任何一种情况下,当任一事件发生时,期限终止.
具体来说,我想要一个observing timer观察函数执行时间的javascript ,如果达到或超过指定时间,observing timer则会停止/通知执行函数.
任何帮助是极大的赞赏!非常感谢.
jfr*_*d00 12
我并不完全清楚你在问什么,但我认为Javascript不能按你想要的方式工作,所以无法完成.例如,无法执行常规函数调用,直到操作完成或持续一定时间(以先到者为准).这可以在javascript之外实现并通过javascript公开(与同步ajax调用一样),但不能在具有常规函数的纯javascript中完成.
与其他语言不同,Javascript是单线程的,因此当一个函数执行时,计时器将永远不会执行(除了Web worker,但它们在他们能做的事情上非常非常有限).定时器只能在函数完成执行时执行.因此,您甚至无法在同步函数和计时器之间共享进度变量,因此计时器无法"检查"函数的进度.
如果你的代码是完全独立的(没有访问你的任何全局变量,没有调用你的其他函数并且无论如何都没有访问过DOM),那么你可以在web-worker中运行它(可用于仅限较新的浏览器)并在主线程中使用计时器.当web-worker代码完成时,它会向主线程发送一条消息及其结果.当主线程收到该消息时,它会停止计时器.如果计时器在接收结果之前触发,则可以终止Web工作者.但是,您的代码必须遵守Web工作者的限制.
Soemthing也可以通过异步操作完成(因为它们可以更好地与Javascript的单线程一起使用),如下所示:
setTimeout()超时时间启动计时器.clearTimeout()并继续.例如,以下是如何在加载图像时设置超时:
function loadImage(url, maxTime, data, fnSuccess, fnFail) {
var img = new Image();
var timer = setTimeout(function() {
timer = null;
fnFail(data, url);
}, maxTime);
img.onLoad = function() {
if (timer) {
clearTimeout(timer);
fnSuccess(data, img);
}
}
img.onAbort = img.onError = function() {
clearTimeout(timer);
fnFail(data, url);
}
img.src = url;
}
Run Code Online (Sandbox Code Playgroud)
我的问题已被标记为与此问题重复,因此我想我会回答它,即使原始帖子已经有九年了。
我花了一段时间才明白 Javascript 单线程的含义(我仍然不确定我是否 100% 理解了),但以下是我如何使用 Promises 和回调解决类似的用例。它主要基于本教程。
首先,我们定义一个timeout函数来包装 Promise:
const timeout = (prom, time, exception) => {
let timer;
return Promise.race([
prom,
new Promise((_r, rej) => timer = setTimeout(rej, time, exception))
]).finally(() => clearTimeout(timer));
}
Run Code Online (Sandbox Code Playgroud)
这是我想要超时的承诺:
const someLongRunningFunction = async () => {
...
return ...;
}
Run Code Online (Sandbox Code Playgroud)
最后我是这样使用的。
const TIMEOUT = 2000;
const timeoutError = Symbol();
var value = "some default value";
try {
value = await timeout(someLongRunningFunction(), TIMEOUT, timeoutError);
}
catch(e) {
if (e === timeoutError) {
console.log("Timeout");
}
else {
console.log("Error: " + e);
}
}
finally {
return callback(value);
}
Run Code Online (Sandbox Code Playgroud)
这将调用该callback函数,并返回值someLongRunningFunction或超时时的默认值。您可以修改它以不同方式处理超时(例如抛出错误)。