У меня есть ряд слайдеров пользовательского интерфейса (dat.GUI), и я отправляю значения слайдера веб-работнику всякий раз, когда слайдер пользовательского интерфейса изменился.
Расчеты, выполненные работнику, должны составлять около 3-8 секунд, пока работник не отправит обратно необходимую мне информацию.
В случае, если интерфейс интерфейса используется с высокой скоростью (например, пять ползунков изменены до завершения первого расчета), рабочий все еще получил пять сообщений и все равно будет реагировать на каждый из них, причем каждый новый переписывая последнюю. Есть ли способ для работника игнорировать промежуточные сообщения и выполнять вычисления только с последним полученным сообщением до завершения текущего расчета?
Я начинаю работать с рабочими, поэтому на данный момент я использую только свойство Worker.onmessage и метод Worker.postMessage().Javascript Web Worker - Как игнорировать все сообщения, кроме последнего?
ответ
Это не имеет ничего общего с WebWorker. Это похоже на типичный вариант использования debounce. Проблема здесь в том, что как только ваш рабочий получит сообщение, как он узнает, что он последний? Он не может сказать о будущем. Он не знает, сделает ли пользователь другое взаимодействие с пользовательским интерфейсом в ближайшем будущем. Таким образом, решение подобных проблем - это отговорка. Идея состоит в том, что вы не выполняете свой код сразу, но подождите немного, скажем, 200 мс. В течение этого периода времени, если было другое сообщение, тогда он будет ждать еще 200 мс, ничего не делая. Вы можете реализовать что-то подобное по своему усмотрению, или вы можете импортировать и использовать одну из существующих библиотек, как underscore.js
EDIT: Вот пример использования 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
возвращает функцию-оболочку, которая может быть вызвана как это часто бывает необходимо. Однако это не приведет к немедленной активации функции, завершенной внутри. Он планирует его выполнить в 200 мс (подстройте его для своих нужд). В течение этого периода, если был другой вызов, ранее запланированное выполнение будет отменено, а новое исполнение будет запланировано на 200 мс на этом этапе. Когда время закончится, ваша функция будет выполнена с последней версией аргументов. Теперь вы, вероятно, задаетесь вопросом, что происходит с аргументами предыдущих вызовов? Ответ заключается в том, что они просто отбрасываются функцией обертки. Обратите внимание, что аргументы, переданные в onmessage
, сначала передаются в функцию-оболочку, которая сохраняет только последнюю, которая будет передана в завернутую функцию. Вы можете играть с созданным здесь fiddle, чтобы увидеть его в действии. Еще одно примечание, которое я хочу добавить, это то, что вы можете сделать эту логику debounce в своем основном потоке, прежде чем передавать его в WebWorker.
EDIT: Если вам необходимо руководство по импорту сторонней библиотеки в WebWorker. https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Importing_scripts_and_libraries
Я решил использовать debounce. Я знаю, как импортировать библиотеку в WebWorker, но я все еще запутался в том, как реализовать эту функцию. Прямо сейчас, у моего работника у меня есть: onmessage = function (e) { // (1 - получить значения, которые были отправлены из основного потока) sliderValues = e.data.sliderValues; // (2 - выполнить вычисления) getMeshInformation(); // (3 - опубликованные результаты) postMessage ({ 'треугольники: треугольники }); }; теперь я только хочу, чтобы 1 выполнялся, а затем ждать (debounce) для no.2 + 3, если он получает новый № 1, который перезаписывает предыдущий. – des
Если вы используете одну из существующих реализаций, все, что вам действительно нужно сделать, это обернуть ваш оригинальный ответ «onmessage» с помощью debounce, и это все, что есть. Однако, если вы хотите сделать свою собственную реализацию, вы можете посмотреть на [underscore.js] (https://github.com/jashkenas/underscore/blob/master/underscore.js#L821) или [lodash] (https://github.com/lodash/lodash/blob/master/lodash.js#L7655) для некоторых вдохновляющих источников. Конечно, ваша реализация не обязательно должна быть такой фантазией. Я отредактирую свой ответ выше, чтобы включить пример, потому что комментарий в комментарии является уродливым. – initialxy
Спасибо за ваше время, это очень полезно. – des
- 1. Rails: Показать все сообщения кроме последнего сообщения
- 2. Как игнорировать все, кроме последней из серии быстрых событий Javascript?
- 3. gmail-сообщения с тем же вопросом - удалить все, кроме последнего
- 4. jQuery выбрать все кроме последнего
- 5. Pandas usecols все кроме последнего
- 6. Удалить все вхождения, кроме последнего?
- 7. Git игнорировать все папки, кроме
- 8. Игнорировать все файлы, кроме одного
- 9. Как соответствовать все, кроме последнего одного
- 10. Как пропустить все, кроме последнего элемента списка?
- 11. Как обновить все строки, кроме последнего?
- 12. Игнорировать все, кроме определенных каталогов, используя .gitignore
- 13. Передача JavaScript-объект в Web Worker
- 14. Перекрестный домен Web Worker?
- 15. игнорировать все, кроме одной директории в .gitignore
- 16. Как git игнорировать все, кроме одной папки?
- 17. Как сообщить Git игнорировать все, кроме подкаталога?
- 18. Как игнорировать все папки dist, кроме одного?
- 19. С Rx, как я могу игнорировать все, кроме самого последнего значения, когда мой метод Subscribe работает
- 20. JavaScript Web Worker - close() vs terminate()
- 21. С javascript удалите все, кроме последнего объекта, на основе значения
- 22. Выделить все, кроме последнего элемента списка
- 23. Удалить все, кроме 1 последнего Баша файла
- 24. Соединить все, кроме последнего х в списке
- 25. Извлечь все, кроме последнего слова + последнее слово
- 26. RegEx strip все, кроме последнего символа
- 27. Все, кроме последнего элемента массива Ruby,
- 28. jQuery/RegEx - возвращает все, кроме последнего номера?
- 29. Выбрать все флажки, кроме последнего определенного элемента
- 30. Итерация через все, кроме последнего индекса массива
Сообщите нам подробнее о вашей архитектуре. Как теперь рабочий, который является последним сообщением? Если это известно заранее, то почему другие сообщения отправляются работнику в первую очередь? – doldt
Как насчет использования ['debounce'] (http://stackoverflow.com/q/24004791/1233508)? Это задерживает обработку бит, и если во время этой задержки получено новое сообщение, он отбрасывает первый и задерживает новый бит, повторяя его до тех пор, пока сообщения не прекратятся. – DCoder
@doldt Все сообщения отправляются, потому что каждый раз, когда изменяется одно значение ползунка, должны выполняться новые вычисления, но в то же время пользователь может продолжать использовать или останавливать использование ползунков в любое время, поэтому я не знаю, какое последнее сообщение отправить только это. «Как бы работник знал, что является последним сообщением», я думаю, это часть моего собственного вопроса. – des