Некоторые заметки о планировании в Монифу - Монифу пытается свернуть асинхронные конвейеры, поэтому, если наблюдатели на нисходящем направлении синхронны по своей природе, то Монифу избежит отправка задач в Планировщик. Monifu также делает противодавление, поэтому он контролирует, сколько задач представлено в Планировщике, поэтому вы не можете попасть в ситуацию, когда очередь браузера взрывается.
Например, что-то вроде этого ... Observable.range(0,1000).foldLeft(0)(_+_).map(_ + 10).filter(_ % 2 == 0)
отправляет только одну задачу в планировщик для запуска этого начального цикла, иначе весь конвейер будет полностью синхронным, если наблюдатель также синхронно и не должен отправлять какие-либо другие задачи в этой очереди. И он отправляет первую задачу в очередь, потому что не имеет представления о том, насколько большой источник будет и обычно подписывается на источник данных, в отношении некоторых обновлений пользовательского интерфейса, которые вы не хотите блокировать.
Есть 3 большие исключения:
- вы используете источник данных, который не поддерживает обратного давления (например, в связи с веб-сокетов)
- у Вас есть реальный асинхронный граница в получает (т.е. наблюдателя), которое может произойти, например, при общении с внешними службами, и это реальное будущее, что вы не знаете, когда она будет завершена
Некоторые решения возможно ...
- в случае, если серверная связь не поддерживает противодавление, в таком случае проще всего изменить сервер для его поддержки - также нормальные HTTP-запросы естественным образом оказывают обратное давление (т.это так же просто, как
Observable.interval(3.seconds).flatMap(_ => httpRequest("..."))
- Если это не вариант, у Monifu есть стратегии буферизации ... поэтому у вас может быть неограниченная очередь, но у вас также может быть очередь, которая вызывает переполнение буфера и закрывает соединение, или буферизация, которая пытается делать резервное нажатие, вы также можете начать отбрасывать новые события, когда буфер заполнен, и я работаю над другой стратегией буферизации для удаления старых событий - с целью избежать выдувных очередей
- , если вы используете «merge» on источник источников, которые могут быть неограниченными, тогда не делайте этого ;-)
- если вы выполняете запросы к внешним службам, попробуйте оптимизировать их - например, если вы хотите отслеживать историю событий, отправив их к веб-службе, вы можете группировать данные и делать batche d и т. д.
BTW - по вопросу о стороне браузера и планировании задач, одна вещь, о которой я беспокоюсь, заключается в том, что Monifu не работает достаточно эффективно. Другими словами, вероятно, он должен разбить более длинные синхронные циклы на более мелкие, потому что хуже, чем проблемы с производительностью, - это проблемы с задержками, видимые в пользовательском интерфейсе, поскольку какой-то цикл блокирует ваши обновления пользовательского интерфейса. Я предпочел бы несколько меньших задач, представленных в Планировщик, вместо более крупного. В браузере у вас в основном есть cooperative multi-tasking, все сделано в том же потоке, включая обновления пользовательского интерфейса, что означает, что очень плохая идея иметь куски работы, которые слишком долго блокируют этот поток.
Тем не менее, я сейчас в процессе оптимизации и уделения большего внимания среде выполнения Javascript. В setTimeout
он используется, потому что он более стандартный, чем setImmediate
, однако я сделаю некоторую работу над этими аспектами.
Но если у вас есть конкретные образцы, производительность которых отстойна, сообщите об этом, так как большинство проблем можно устранить.
Приветствия,
Это, конечно, лучше использовать 'setImmediate' (или polyfill) вместо' setTimeout' для микро-задач. 'setTimeout' является дорогостоящим, я сделал некоторое время [здесь] (http://stackoverflow.com/q/18826570/1768303). – Noseratio
Это отличный тест. «Спецификация HTML5 дошла до того, что она рекомендовала 250 обратных вызовов setTimeout в секунду». Я думаю, что на некоторых этапах выполнения моего приложения я мог бы выполнять больше, чем это ... – lisak
По умолчанию 'setTimeout()' имеет минимальное количество мс до его вызова, поэтому это зависит от того, хотите ли вы эту функцию это или нет. Я сомневаюсь, что есть проблемы с очередями, поскольку это относительно небольшой объем данных для очереди в событии, и многие реализации таймеров используют один системный таймер среди всех таймеров, что возможно, потому что они не упреждающие. Если вы хотите выполнить микрозадание в течение 1-2 мс, то 'setTimeout()' является неправильным инструментом. – jfriend00