gpt4 book ai didi

javascript - 我可以检测挂起的 JS 函数并中止吗?

转载 作者:行者123 更新时间:2023-12-04 08:07:28 27 4
gpt4 key购买 nike

我正在开发一种工具,它允许用户为查找和替换输入正则表达式,然后我的工具将执行该查找和替换并返回更改后的文本。但是,我最近遇到了 find&replace 简单卡住的情况,因此我决定最好以某种方式检测正则表达式匹配问题,并在经过一定时间后中止。
我查了一下,使用 this answer 能找到什么是我遇到的问题被称为“灾难性回溯”。知道这是理想的,因为这样我可以制作一个最小的工作示例来说明哪里出错了,但是如果解决 change the regular expression 就不理想了不可能,因为我无法控制用户的正则表达式输入(并且我无法编写足够高级的正则表达式解析器来限制用户的正则表达式使用以排除此类情况)。
所以为了解决这个问题,我尝试使用 promises,正如 this answer 中所建议的那样。 .我在这个例子中制作了“灾难性”匹配字符串,长度刚好足以让我的标签悬挂几秒钟,而不会完全破坏标签。不过,不同的计算机规范可能会看到不同的结果,我不确定。
单挑:执行此代码可能会卡住您当前的选项卡。请确保您在执行此代码时没有编写部分答案,因为它可能会导致工作丢失。

var PTest = function () {
return new Promise(function (resolve, reject) {
setTimeout(function() {
reject();
}, 100)
"xxxxxxxxxxxxxxxxxxxxxxxxx".match(/(x+x+)+y/)
resolve();
});
}
var myfunc = PTest();
myfunc.then(function () {
console.log("Promise Resolved");
}).catch(function () {
console.log("Promise Rejected");
});

在我的计算机上,这会导致选项卡在控制台中显示“Promise Resolved”之前卡住大约 4 秒钟。
我现在的问题是:如果执行时间太长(在示例中:超过 0.2 秒),是否有可能“中止”这样的脚本的执行?我宁愿杀死正则表达式查找和替换,也不愿使工具完全崩溃,从而导致用户失去工作。

最佳答案

我建议使用 Web Worker,因为它会在自己的沙箱中运行:https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
Web Worker 是它自己的脚本,您需要将其包含在 JavaScript 中,例如:

var worker = new Worker('/path/to/run-regex.js');
以下是未经测试的代码,但应该可以帮助您。
您的 run-regex.js (可能长时间运行)正则表达式是否匹配:
function regexMatch(str, regexStr, callback) {
let regex = new RegExp(regexStr);
let result = str.match(regex);
callback(result, '');
}

onmessage = function(e) {
let data = e.data;
switch (data.cmd) {
case 'match':
regexMatch(data.str, data.regex, function(result, err) {
postMessage({ cmd: data.cmd, result: result, err: err });
});
break;
case 'replace':
//regexMatch(data.str, data.regex, data.replace, function(result, err) {
// postMessage({ cmd: data.cmd, result: result, err: err });
//});
break;
default:
break;
postMessage({ err: 'Unknown command: ' + data.cmd });
}
}
在您自己的脚本中,加载 Web Worker,并添加一个事件监听器:
if(window.Worker) {
const myWorker = new Worker('/path/to/run-regex.js');

myWorker.onmessage = function(e) {
let data = e.data;
if(data.err) {
// handle error
} else {
// handle match result using data.result;
}
}

function regexMatch(str, regex) {
let data = { cmd: 'match', str: str, regex: regex.toString() };
myWorker.postMessage(data);
}

regexMatch('xxxxxxxxxxxxxxxxxxxxxxxxx', /(x+x+)+y/);

} else {
console.log('Your browser does not support web workers.');
}
这样,当工作程序工作时,您的主 JavaScript 线程是非阻塞的。
如果是长时间运行的工作程序,您可以将代码添加到:
  • 使用 myWorker.terminate() 不优雅地终止 web worker ,然后重新启动它——见 Is it possible to terminate a running web worker?
  • 或者,尝试 close()从网络 worker 范围内 - 见 JavaScript Web Worker - close() vs terminate()
  • 关于javascript - 我可以检测挂起的 JS 函数并中止吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66153487/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com