Javascript Web Worker - 如何忽略除最后一条消息之外的所有消息?
Javascript Web Worker - How to ignore all messages except the last one?
我有一系列 UI 滑块 (dat.GUI),只要 UI 滑块发生变化,我就会将滑块值发布给网络工作者。
在工作人员中完成的计算大约需要 3-8 秒,直到工作人员回传我需要的信息。
如果 UI 接口被快速使用(例如,在第一次计算完成之前更改了五个滑块),worker 仍会收到五条消息,并且仍将响应每条消息,每条消息新信息覆盖上一个。 worker有没有办法忽略中间的消息,只用当前计算完成前最后收到的消息进行计算?
我是工人的初学者,所以现在我只使用 Worker.onmessage 属性 和 Worker.postMessage() 方法。
这与 WebWorker 没有太大关系。这似乎是一个典型的去抖动用例。这里的问题是,一旦您的工作人员收到一条消息,它怎么知道这是最后一条消息?它不能预知未来。它不知道用户是否会在不久的将来进行另一次 UI 交互。所以解决这类问题的办法就是debounce。这个想法是您不会立即执行您的代码,而是稍等片刻,比如 200 毫秒。在这段时间内,如果再有消息,那么它会再等待200ms,什么都不做。你可以自己实现类似的东西,或者你可以导入和使用现有的库之一,比如 underscore.js
编辑:这是一个使用下划线的例子。js/lodash(两者都有相似的API)。
假设最初,您的代码是这样的:
onmessage = function(e) {
var params = e.data.something;
// TODO: Do something with params.
};
有了 debounce,你会把它改写成...
onmessage = _.debounce(function(e){
var params = e.data.something;
// TODO: Do something with params.
}, 200);
这里发生的事情是 _.debounce
returns 一个可以根据需要频繁调用的包装函数。但是它不会立即触发包裹在里面的功能。它安排它在 200 毫秒内执行(根据您的需要调整它)。在此期间,如果再有调用,会取消之前的调度执行,此时会在200ms后调度新的执行。时间到了,您的函数将使用最新版本的参数执行。现在您可能想知道之前调用的参数发生了什么?答案是它们只是被包装函数丢弃了。请注意,传递给 onmessage
的参数首先传递给包装函数,它只保留最新的参数传递给包装函数。您可以使用我在此处创建的 fiddle 来查看它的实际效果。我想补充的另一个注意事项是,在将它传递给 WebWorker 之前,您也可以在主线程上执行此反跳逻辑。
编辑: 如果您需要有关如何在 WebWorker 中导入第三方库的指南。 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Importing_scripts_and_libraries
我有一系列 UI 滑块 (dat.GUI),只要 UI 滑块发生变化,我就会将滑块值发布给网络工作者。
在工作人员中完成的计算大约需要 3-8 秒,直到工作人员回传我需要的信息。
如果 UI 接口被快速使用(例如,在第一次计算完成之前更改了五个滑块),worker 仍会收到五条消息,并且仍将响应每条消息,每条消息新信息覆盖上一个。 worker有没有办法忽略中间的消息,只用当前计算完成前最后收到的消息进行计算?
我是工人的初学者,所以现在我只使用 Worker.onmessage 属性 和 Worker.postMessage() 方法。
这与 WebWorker 没有太大关系。这似乎是一个典型的去抖动用例。这里的问题是,一旦您的工作人员收到一条消息,它怎么知道这是最后一条消息?它不能预知未来。它不知道用户是否会在不久的将来进行另一次 UI 交互。所以解决这类问题的办法就是debounce。这个想法是您不会立即执行您的代码,而是稍等片刻,比如 200 毫秒。在这段时间内,如果再有消息,那么它会再等待200ms,什么都不做。你可以自己实现类似的东西,或者你可以导入和使用现有的库之一,比如 underscore.js
编辑:这是一个使用下划线的例子。js/lodash(两者都有相似的API)。 假设最初,您的代码是这样的:
onmessage = function(e) {
var params = e.data.something;
// TODO: Do something with params.
};
有了 debounce,你会把它改写成...
onmessage = _.debounce(function(e){
var params = e.data.something;
// TODO: Do something with params.
}, 200);
这里发生的事情是 _.debounce
returns 一个可以根据需要频繁调用的包装函数。但是它不会立即触发包裹在里面的功能。它安排它在 200 毫秒内执行(根据您的需要调整它)。在此期间,如果再有调用,会取消之前的调度执行,此时会在200ms后调度新的执行。时间到了,您的函数将使用最新版本的参数执行。现在您可能想知道之前调用的参数发生了什么?答案是它们只是被包装函数丢弃了。请注意,传递给 onmessage
的参数首先传递给包装函数,它只保留最新的参数传递给包装函数。您可以使用我在此处创建的 fiddle 来查看它的实际效果。我想补充的另一个注意事项是,在将它传递给 WebWorker 之前,您也可以在主线程上执行此反跳逻辑。
编辑: 如果您需要有关如何在 WebWorker 中导入第三方库的指南。 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Importing_scripts_and_libraries