2014-11-03 4 views
17

В JavaScript шаблон наблюдателя используется довольно часто. В этом есть одна сложная вещь, и это ссылки, которые хранит наблюдатели. Они требуют очистки. Для обычных приложений я использую следующие эмпирические правила:Является ли функциональное реактивное программирование в JavaScript причиной больших проблем со ссылками слушателя?

  • Если объект имеет срок службы короче (или равно) наблюдатель, я могу просто сделать subject.on('event', ...)
  • Если объект имеет срок службы больше чем наблюдатель, мне нужно использовать observer.listenTo(subject, 'event', ...)

Во втором случае listenTo знает о жизненном цикле наблюдателя, и он будет автоматически удалять слушателей, когда пришло время для наблюдателя, чтобы умереть.

В современном стиле SPA (Single Page Application), где в любой момент активны только части приложения, это становится очень важным. Если вы объедините это с веб-сокетами, которые являются идеальным кандидатом на поток событий и, скорее всего, долговечны, это становится еще более важным.

С FRP, имеющим нечто вроде потока событий, представляющего изменяющиеся значения с течением времени, я (не зная об этом) создаю много слушателей. Каждый filter, map и flatMap создает новый поток, связанный (возможно, с прослушивателем) с предыдущим.

На мой взгляд, кажется довольно сложным определить, как и когда мне нужно удалить этих слушателей. Я не могу представить, чтобы я был первым, кто подумал об этой проблеме, но я не мог найти много об этом в Интернете.

Я видел, что некоторые фреймворки на других языках используют слабые ссылки. JavaScript не имеет понятия слабых ссылок (WeakMap здесь не используется). Даже если бы это имело хотя бы, это кажется плохой идеей, потому что неясно, когда происходит сбор мусора.

  • Как это можно решить в современных рамках?
  • Связаны ли рамки с жизненным циклом объектов? Если да: как?
+1

Если вы считаете, что этот вопрос должен быть закрыт, пожалуйста, добавьте комментарий. Возможно, добавьте предложение, чтобы сделать вопрос более конкретным. Или, может быть, указатель на место, где этот вопрос лучше подходит. Если неясно, задайте вопросы. Я действительно хочу использовать FRP. – EECOLOR

+0

Извините, что мне пришлось голосовать, чтобы закрыть. Этот вопрос слишком открытый. –

+0

@JK. Есть ли у вас предложения по улучшению вопроса? – EECOLOR

ответ

11

В RxJs каждый Observer по умолчанию имеет отдельный прослушиватель исходного источника события. Итак, если у вас есть

var s = $('#textInput').keyupAsObservable() 
s.subscribe(subscriber1); 
s.map(function() {}).subscribe(subscriber2); 

У вас будет два прослушивателя клавиатуры. Вы можете использовать .publish().refCount(), чтобы Observable поддерживал одно соединение со своим источником.

В Bacon.js, наблюдатели всегда поддерживают одно соединение с их источником.

В обеих библиотеках соединение с источником создается лениво (при добавлении Observer) и автоматически удаляется при удалении (последнего) наблюдателя. Поэтому вам не нужно вручную управлять слушателями.

Однако в случае, когда subject имеет более длительный срок службы, чем Observer, вам необходимо убедиться, что наблюдатель прекращает подписку, когда срок ее службы заканчивается, или у вас будет утечка. Ни у каких библиотек нет «магического» способа управления этим, потому что в библиотеке ваш Observer - это просто функция.

Лично я часто создать Observable называется death или независимо от того, чтобы сигнализировать об окончании срока их использования для наблюдателя, а затем вместо того, чтобы подписаться на subject подписаться на subject.takeUntil(death).

Что касается Elm, я понимаю, что вы сразу создали всю сеть событий, поэтому нет возможности утечки; Observers не могут быть добавлены на более позднем этапе.

+0

Ваше понимание Вязов является правильным, поэтому вы можете быть более напористым в этом последнем утверждении. Язык разрешает только статические сети событий (сигнальные графы, так называемые в Elm), поэтому код может быть (и есть) скомпилирован в JavaScript, который строит полную сеть во время инициализации и не должен иметь дело с подпиской/отпиской. – Apanatshka

+0

«Смерть» - интересная концепция. Приятно знать, что ни одна из предложенных вами структур не имеет ничего общего с жизненным циклом. – EECOLOR

 Смежные вопросы

  • Нет связанных вопросов^_^