gpt4 book ai didi

javascript - html/javascript 中长时间运行的代码

转载 作者:行者123 更新时间:2023-11-29 16:40:40 26 4
gpt4 key购买 nike

我需要在单击按钮时在浏览器中运行算法。用 javascript 编码非常复杂,而且速度会很慢。有没有推荐的架构?理想情况下,我想用 C++ 或 Python 对其进行编码,但我想不可能在单击按钮时在浏览器中运行它。那么,我的下一个最佳选择是什么?

我无法让它在服务器端运行,因为页面上会有数千次点击,这将导致过多的来回通信。

最佳答案

So, what are my next best options

使用 Web Worker( specificationMDN ),以便计算不在主 UI 线程上运行。工作人员甚至可以将更新发布到主线程以显示进度。


根据您对问题的评论:

It needs to be synchronous operation i.e on click...

这并不符合,并且您真的希望它是同步的,如果它正在做繁重的工作,您将锁定浏览器的 UI。

如果您需要在处理过程中防止进一步点击,只需在按钮运行时禁用该按钮即可。

下面是一个计算 10 亿阶乘的示例(即使在现代浏览器上也需要一些时间),每百万次来自工作线程的更新:

HTML:

<input type="button" class="the-btn" value="Click To Start">
<div>
<div class="progress-wrapper">
<div class="progress-bar"></div>
</div>
<div class="progress-counter">-</div>
</div>
<div class="result"></div>

CSS:

.progress-wrapper {
border: 1px solid black;
display: inline-block;
width: 70%;
height: 1em;
}
.progress-bar {
display: inline-block;
width: 0;
background-color: blue;
height: 1em;
}
.progress-counter {
display: inline-block;
}

factorial_worker.js:

self.onmessage = function(e) {
if (e.data && e.data.type === "start") {
var n = 0, max = 1000000000, result = 0;
while (n < max) {
if (n % 1000000 === 0) {
self.postMessage({type: "progress", progress: (n / max) * 100});
}
result += n;
++n;
}
self.postMessage({type: "done", result: result});
}
};

页面中的主要脚本:

// Get the worker
var worker = new Worker("factorial_worker.js");

// Get our various elements
var btn = document.querySelector(".the-btn");
var progressBar = document.querySelector(".progress-bar");
var progressCounter = document.querySelector(".progress-counter");
var result = document.querySelector(".result");

function setProgress(progress) {
var percent = progress.toFixed(2) + "%";
console.log("Progress: " + percent);
progressCounter.innerHTML = percent;
progressBar.style.width = percent;
}

// Handle clicks
btn.addEventListener("click", function() {
// Disable the button and tell the worker to get started
worker.postMessage({type: "start"});
result.innerHTML = "Working...";
btn.disabled = true;
});

// Handle a message from the worker
worker.onmessage = function(e) {
switch (e.data.type) {
case "progress":
setProgress(e.data.progress);
break;
case "done":
// Re-enable the button
btn.disabled = false;
setProgress(100);
result.innerHTML = "Result: " + e.data.result;
break;
}
};

实时示例(使用将工作程序嵌入页面的技巧,因为我们无法在 Stack Snippets 上处理外部文件):

// <ignore> Ignore this bit, it's just because we can't have a separate file in Stack Snippets
var blob = new Blob([
document.querySelector(".the-worker").textContent
], { type: "text/javascript" });
// </ignore>

// Get the worker
// In your own code, you'd refer to a JavaScript file here:
// var worker = new Worker("my_worker_script.js");
var worker = new Worker(window.URL.createObjectURL(blob));

// Get our various elements
var btn = document.querySelector(".the-btn");
var progressBar = document.querySelector(".progress-bar");
var progressCounter = document.querySelector(".progress-counter");
var result = document.querySelector(".result");

function setProgress(progress) {
var percent = progress.toFixed(2) + "%";
progressCounter.innerHTML = percent;
progressBar.style.width = percent;
}

// Handle clicks
btn.addEventListener("click", function() {
// Disable the button and tell the worker to get started
worker.postMessage({type: "start"});
result.innerHTML = "Working...";
btn.disabled = true;
});

// Handle a message from the worker
worker.onmessage = function(e) {
switch (e.data.type) {
case "progress":
setProgress(e.data.progress);
break;
case "done":
// Re-enable the button
btn.disabled = false;
setProgress(100);
result.innerHTML = "Result: " + e.data.result;
break;
}
};
.progress-wrapper {
border: 1px solid black;
display: inline-block;
width: 70%;
height: 1em;
}
.progress-bar {
display: inline-block;
width: 0;
background-color: blue;
height: 1em;
}
.progress-counter {
display: inline-block;
}
<input type="button" class="the-btn" value="Click To Start">
<div>
<div class="progress-wrapper">
<div class="progress-bar"></div>
</div>
<div class="progress-counter"></div>
</div>
<div class="result"></div>
<script class="the-worker" type="javascript/worker">
// This script won't be parsed by JS engines because its type is javascript/worker.
self.onmessage = function(e) {
if (e.data && e.data.type === "start") {
var n = 0, max = 1000000000, result = 0;
while (n < max) {
if (n % 1000000 === 0) {
self.postMessage({type: "progress", progress: (n / max) * 100});
}
result += n;
++n;
}
self.postMessage({type: "done", result: result});
}
};
</script>

关于javascript - html/javascript 中长时间运行的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46346297/

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