logo

Остановка и сброс функции $watch в AngularJS: практический гид

Быстрый ответ

Для того чтобы отменить $watch немедленно, используйте функцию-отмену, которая возвращается при установке $watch:

JS
Скопировать код
var unwatch = $scope.$watch('property', (newVal, oldVal) => {
    // Ваш код, реагирующий на изменения значения
});

// Чтобы прекратить наблюдение...
unwatch(); // Вот и всё, наблюдение прекращено

Данная функция прекращает отслеживание изменений свойства property, что поможет экономить системные ресурсы.

Различные сценарии, различные решения

Когда пришло время прекратить наблюдение

Иногда $watch необходимо остановить при определённых условиях. Для этого вызывайте функцию-отмену прямо в функции-обработчике $watch:

JS
Скопировать код
var unwatch = $scope.$watch('property', function(newValue) {
    if (newValue === "Достаточно!") {
        unwatch(); // Задача выполнена, спасибо!
    }
});

Как контролировать множество наблюдений

Если вам необходимо контролировать несколько $watch, вот эффективный способ этого сделать:

JS
Скопировать код
let watches = [];
watches.push($scope.$watch('property1', callback1, true));
watches.push($scope.$watch('property2', callback2, true));

// Когда наблюдатели отработали
watches.forEach(unwatch => unwatch());
watches = []; // Очищаем список

Временные наблюдения

Можно ограничить время работы $watch, воспользовавшись setTimeout или $timeout от AngularJS, чтобы автоматически остановить его:

JS
Скопировать код
var unwatch = $scope.$watch('property', callback);

$timeout(function() {
    unwatch(); // Наблюдение завершилось
}, 3000);

Визуализация

В таблице представлен жизненный цикл $watch:

  • При установке $watch: ✅
  • После вызова unwatch(): ❌
JS
Скопировать код
let unwatch = $scope.$watch('myVariable', function(newValue, oldValue) {
  // Обучаемся на ошибках
});

// Пришло время расстаться
unwatch(); // Время отпускать

Emoji-схема процесса:

Markdown
Скопировать код
До `unwatch`: [🏠] --- 📬 ---> [📰]
После `unwatch`:  [🏠] -x- 🚫 -x- [📭]

🏠 символизирует $scope, 📬 обозначает активное наблюдение через $watch, 📰 указывает на обновление данных, а 🚫 демонстрирует прекращение подписки (обновления больше не приходят).

Лучшие практики: Как избавиться от лишних $watch

Одноразовые наблюдения

Используйте $watch для единоразовых операций, когда это необходимо:

JS
Скопировать код
$scope.$watch('oneTimeProperty', function (newValue, oldValue) {
    if (newValue === oldValue) return; // Если ничего не изменилось, выходим

    // Выполняем целевое действие
    doSomething(newValue);

    unwatch(); // Пора освобождать ресурсы
});

Улучшаем производительность приложения

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

Полезные материалы

  1. Официальная документация AngularJS – раздел про $watch.
  2. Взаимодействие контроллеров в AngularJS – Stack Overflow – гайд по отмене подписки на события.
  3. Отмена $watch в AngularJS – Ben Nadel – лучшие практики по отписке от событий.
  4. Жизненный цикл $scope в AngularJS – подробное объяснение.
  5. Поиск утечек памяти в JavaScript – Tech TLDR; – советы по определению утечек памяти.
  6. Ошибки разработчиков AngularJS – Toptal® – советы по повышению производительности и типичные ошибки.