Главная » Статьи » Улучшенная навигация и маршрутизация в Angular 7 с помощью switchMap

Улучшенная навигация и маршрутизация в Angular 7 с помощью switchMap

Улучшенная навигация и маршрутизация в Angular 7 с помощью switchMap

От автора: с PR #25740 все навигации, выполняемые маршрутизатором Angular, объединяются в один наблюдаемый поток. Также в любое время может быть только одна активная навигация. Это обеспечивает преимущества более быстрой и предсказуемой навигации. Хотя эти изменения в основном являются внутренними, они влияют на понимание того, как работают в приложениях Angular маршрутизация и навигация

Это главный рефакторинг работы маршрутизатора. У него есть несколько основных преимуществ, и будущие инструменты будут построены на его основе.

Эти изменения были введены как часть Angular 7.0. В этой статье мы рассмотрим данные изменения и то, как их можно использовать. Мы также увидим, как switchMap, обеспечивает, чтобы только одна навигация могла выполняться в одно и то же время может.

Понимание навигации

Навигация происходит всякий раз, когда изменяется URL-адрес. Это может быть результатом какого-либо императивного действия (вызова службой navigate) или другого действия, такого, как нажатие пользователем директивы [routerLink]. После начала навигация проходит следующие этапы:

Процесс перенаправления

URL для соответствия пути

Запуск guard-ов и resolver-ов

Рендеринг компонентов и обновление местоположения браузера

Проблема

До #25740 было возможно запускать несколько переходов одновременно. Как вы можете себе представить, это может вызвать проблемы. Рассмотрим следующий сценарий:

Пользователь нажимает на ссылку X. Начинается новая навигация с id1.

Во время перехода к X гарды и резольверы работают асинхронно, и их выполнение занимает 10 секунд.

В течение этих 10 секунд пользователь теряет терпение и нажимает на ссылку Y, которая начинает новую навигацию к Y, с id2.

Навигация 2 должна дождаться завершения работы гардов и резольверов навигации 1 (результаты которых будут игнорироваться).

Возможно, один из гардов в навигации 1 дает сбой и инициирует перенаправление во время ожидания навигации 2. Сейчас трудно сказать, куда попадет пользователь.

Короче говоря, управление одновременной навигацией было запутанным как внутри, так и вне фреймворка. С изменениями, внесенными в 25740, в каждый момент времени может быть только одна активная навигация. Как мы увидим, это решает многие проблемы и упрощает навигацию.

Изменения

Основные внутренние изменения в 25740 заключаются в следующем:

Каждый этап цикла навигации теперь представлен собственным оператором (перенаправления, распознавание маршрута и т. д.)

Эти операторы проходят через switchMap, что гарантирует, что будет рассматриваться только самая последняя навигация. И это отменит и очистит любые ожидающие навигации.

Подробное описание

Одна карта может выполнять все изменения

Как упоминалось ранее, новое правило «одна навигация за один раз» применяется могущественным оператором switchMap. Благодаря созданию единого наблюдаемого потока и конвейеризации всех переходов через маршрутизатор switchMap вместо mergeMap, любая новая навигация приведет к отмене и очистке предыдущей навигации switchMap.

* Рефакторинг switchMap вместо предыдущего mergeMap заключается в том, чтобы новые навигации вызывали отмену и очистку уже запущенных навигаций — выдержка из PR 25740

Пользовательские операторы

Начиная с 25740, различные части процесса навигации были преобразованы в пользовательские операторы, которые размещаются в /packages/router/src/operators. Вы можете видеть, что каждый из упомянутых ранее этапов навигации теперь представлен операторами:

apply_redirects.ts

recognize.ts

check_guards.ts и resol_data.ts

activate_routes.ts

Внутренне переходы между навигациями представлены типом NavigationTransition. Наблюдаемый поток NavigationTransition с именем router.transitions используется с главным наблюдаемым потоком router.navigations для обработки новой навигации. Это то место, где используется switchMap для отмены любой текущей навигации, когда происходит новая навигация.

private setupNavigations(transitions: Observable<NavigationTransition>): Observable<NavigationTransition> { return transitions.pipe( filter(t => t.id !== 0), // Extract URL map(t => ({...t, extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl)}) as NavigationTransition), // Using switchMap so we cancel executing navigations when a new one comes in
switchMap(t => {

Вы можете увидеть весь поток, если ознакомитесь с SetupNavigations в router.ts.

Преимущества

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

К счастью, все эти изменения являются внутренними. Так что на самом деле вам не нужно ничего менять в своих приложениях. Просто знайте, что у вас может быть только одна активная навигация в одно время.

Заключение

С изменениями в 25740:

В любое время активна только одна навигация.

Когда запускается новая навигация, любая ожидающая навигация отменяется и очищается.

Внутренне каждый этап цикла навигации разбит на отдельные операторы.

Эти изменения должны обеспечить более быструю и надежную навигацию.

Удачной навигации!

Автор: Nate Lapinski

Источник: https://blog.angularindepth.com/

Редакция: Команда webformyself.