我正在尝试编写一个执行可中断计算的网络工作者。Worker.terminate()
我知道这样做的唯一方法(除了)是定期让步给消息循环,以便它可以检查是否有任何新消息。例如,这个网络工作者计算从 0 到 的整数之和data
,但是如果您在计算过程中向它发送一条新消息,它将取消计算并开始新的计算。
let currentTask = {
cancelled: false,
}
onmessage = event => {
// Cancel the current task if there is one.
currentTask.cancelled = true;
// Make a new task (this takes advantage of objects being references in Javascript).
currentTask = {
cancelled: false,
};
performComputation(currentTask, event.data);
}
// Wait for setTimeout(0) to complete, so that the event loop can receive any pending messages.
function yieldToMacrotasks() {
return new Promise((resolve) => setTimeout(resolve));
}
async function performComputation(task, data) {
let total = 0;
while (data !== 0) {
// Do a little bit of computation.
total += data;
--data;
// Yield to the event loop.
await yieldToMacrotasks();
// Check if this task has been superceded by another one.
if (task.cancelled) {
return;
}
}
// Return the result.
postMessage(total);
}
这有效,但速度非常慢。在while
我的机器上,循环的平均每次迭代需要 4 毫秒!如果您希望取消快速发生,那将是一个相当大的开销。
为什么这么慢?有没有更快的方法来做到这一点?