Ответ 1
Итак, это на самом деле довольно прямолинейно, на базовом уровне задействованы 2 типа функций:
-
Функции, которые создают реактивный контекст (реактивная функция)
-
Функции, которые недействительны для реактивного контекста (функция недействительности)
-
Функции, которые могут выполнять оба. (Я соврал там 3)
Когда вы вызываете reactive function
, он создает context
, который хранит метеориты по всему миру и к которому reactive function
подписывается обратный вызов invalidation
. Функция, которую вы передаете реактивной функции или любые функции, которые запускаются внутри нее, может быть invalidating function
и может захватывать текущий context
и сохранять ее локально. Эти функции могут тогда в любой момент, например, при обновлении db или просто вызове таймера, недействительны, что context
. Первоначальный reactive function
затем получит это событие и переоценит себя.
Здесь шаг за шагом, используя функции метеора (обратите внимание, что Tracker.autorun
называлось Deps.autorun
):
Tracker.autorun(function(){
alert("Hello " + Session.get("name"));
});
Session.set("name", "Greg");
- autorun принимает функцию в качестве параметра
- до запуска этой функции автозапуск создает
context
- autorun присоединяет обратный вызов к событию недействительности
context
- Этот обратный вызов будет повторно запускать функцию, переданную автозагрузчику
- Функция затем запускается в
context
в первый раз. - Meteor сохраняет этот
context
глобально как текущий активныйcontext
- Внутри функции есть еще одна функция: Session.get()
- Session.get() является как
reactive function
, так иinvalidating function
- Session.get устанавливает свой собственный
context
и связывает его внутри с ключом "имя" - Session.get извлекает текущий контекст (контекст автозапуска) глобально из метеора
- Обратный вызов недействительности, который Session.get регистрирует в своем собственном контексте, просто приведет к недействительности его включения контекста (в данном случае контекста автозапуска)
- Итак, теперь у нас есть 2 контекста: autorun и session.get
-
когда эти функции возвращаются, метеорит очищает глобальную переменную активного контекста
-
Session.set - это еще одна функция, которая может привести к недействительности
context
. - в этом случае мы аннулируем все
context
, созданные сеансом, связанным с ключом "имя" - Все те
contexts
, когда они недействительны, запускают свои обратные вызовы недействительности. - Эти обратные вызовы просто недействительны для их включения
context
(что дизайн Session.get, а не то, что должен делать обратный вызов недействительности) - Те, кто заключает
contexts
, теперь выполняют свои обратные вызовы недействительности. - В случае автозапуска этот обратный вызов запускает функцию, которую мы первоначально передали автозапуску, а затем снова устанавливает
context
.
Вся реализация на самом деле довольно прямолинейна, вы можете увидеть ее здесь:
https://github.com/meteor/meteor/blob/master/packages/tracker/tracker.js
И хороший пример того, как это работает, можно найти здесь:
https://github.com/meteor/meteor/blob/master/packages/reactive-dict/reactive-dict.js
Реактивное программирование на самом деле не является метеорным или JS-специфическим
вы можете прочитать об этом здесь: http://en.wikipedia.org/wiki/Reactive_programming