Javascript Web Worker - 如何忽略除最后一条消息之外的所有消息?

时间:2015-07-11 17:21:09

标签: javascript web-worker postmessage

我有一系列UI滑块(dat.GUI),每当UI滑块发生变化时,我都会将滑块值发布给Web worker。
在工人中进行的计算需要大约3-8秒,直到工人回复我需要的信息为止。

如果以快速率使用UI界面(例如,在完成第一次计算之前更改了五个滑块),则工作人员仍然收到五条消息并仍将响应其中的每一条,每条新信息都会覆盖最后一个。在当前计算完成之前,工人是否有办法忽略中间消息并仅使用上次收到的消息执行计算?

我是工作者的初学者,所以现在我只使用Worker.onmessage属性和Worker.postMessage()方法。

1 个答案:

答案 0 :(得分:2)

这与WebWorker没有多大关系。这似乎是一个典型的去抖用例。这里的问题是,一旦你的工人收到一条消息,它怎么知道它是最后一个?它无法告诉未来。它不知道用户是否会在不久的将来进行另一次UI交互。所以这种问题的解决方案是去抖动。这个想法是你不会马上执行你的代码,但要稍微等一下,比如说200ms。在这段时间内,如果有另一条消息,那么它将等待另外200毫秒而不做任何事情。你可以自己实现这样的东西,或者你可以导入和使用现有的一个库,如underscore.js

编辑:以下是使用underscore.js / lodash的示例(两者都有类似的API)。 假设最初,您的代码是这样的:

onmessage = function(e) {
    var params = e.data.something;
    // TODO: Do something with params.
};

使用去抖动,你会将其重写为......

onmessage = _.debounce(function(e){
    var params = e.data.something;
    // TODO: Do something with params.
}, 200);

这里发生的是_.debounce返回一个可以根据需要频繁调用的包装函数。但是它不会立即触发包裹在里面的功能。它安排它在200ms内执行(根据您的需要调整它)。在此期间,如果有另一个呼叫,则先前计划的执行将被取消,此时将在200ms内安排新的执行。当时间到了,你的函数将使用最新版本的参数执行。现在你可能想知道之前调用的参数会发生什么变化?答案是它们被包装函数简单地丢弃了。请注意,传递给onmessage的参数首先传递给包装函数,它只保留最新的参数传递给包装函数。您可以使用我在此处创建的fiddle来观看它的实际效果。我要补充的另一个注意事项是,在将其传递给WebWorker之前,您也可以在主线程上执行此去抖逻辑。

编辑:如果您需要有关如何在WebWorker中导入第三方库的指南。 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Importing_scripts_and_libraries