Угловое обещание от ActivatedRoute не работает с Typescript await

Чтобы получить доступ к компонентам в текущем URL-пути, в моем приложении работает следующее:

constructor(private route: ActivatedRoute) { }
...
load() {
    this.route.params.subscribe((params) => {
      const id = +params['id'];
      console.info('got parameter', id);
 ... etc

Это случай из учебника, и переменная я бы устанавливается как объявлено. Но я хочу использовать более элегантную форму Ждите, и она не работает. (Конечно, у меня будет следующая строка операторов Ждите.) Вот так:

async load() {
    try {
      console.info('getting parameters');
      const params = await this.route.params.toPromise();
      console.info('got params', params);
      const id = +params['id'];
  ... etc

Я получаю результат первого вызова console.info (), но второй так и не приходит. И, конечно же, переменная я бы не устанавливается, а остальная часть кода никогда не выполняется.

В документации и рабочем коде сказано, что this.route.params - это Наблюдаемый, который должен быть преобразован в Обещать через обещать() и, таким образом, использоваться с Typescript асинхронный / Ждите. Я использую операторы Ждите с Наблюдаемые, которые отлично выходят из модуля HttpClient.

Но это не работает. Кто-нибудь знает почему?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
0
1 634
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Основной ответ: У вас здесь неконтролируемые условия гонки

Когда вы получаете доступ к Observable route.params, вполне нормально, что он еще не завершен. Вызов toPromise() на нем в этот момент приведет к постоянно ожидаемому обещанию, и это проблема, с которой вы столкнулись.

Если вы не обязаны использовать эту конструкцию async await, оставьте ее и лучше напрямую обращаться к params.id синхронно через ActivatedRouteSnapshot.

ngOnInit() {
    const id: string = route.snapshot.params.id;
}

Пожалуйста, не забудьте отметить этот ответ как решение, если он решил вашу проблему или ответил на ваш вопрос. Заранее спасибо.

Lynx 242 01.08.2018 07:25

Да, это сработало, но я не понимаю, почему в примерах, которым я следовал, использовалась форма Observables, что привело меня так далеко в заблуждение. Вдобавок я не понимаю, почему ActivatedRoute вообще использует Observables. Почему бы не установить маршрут и URL-адрес или статические во время создания компонента? Ну что ж, я исследую это позже. Спасибо за указатель.

AlanObject 01.08.2018 08:24

По поводу вопроса ... почему ActivatedRoute вообще использует Observables ... AlanObject, причина в том, что ngOnInit() вызывается только при инициализации компонента, то есть при его создании. Представьте, что ваш компонент используется для отображения сведений об элементе с таким маршрутом, как /item/123, где 123 - текущий элемент ID.

Теперь, если ваш компонент будет реализовывать также ссылки Предыдущий и Следующий, ведущие к /item/122 и /item/124, компонент не будет создаваться снова. В таких случаях вам потребуется подписка или другой способ обновления ID и связанных данных.

Другие вопросы по теме