Промисы против наблюдаемых для миграции с AngularJS на Angular

AngularJS (Angular 1) активно использовал Promises для вызовов HTTP, в то время как Angular 2+ имеет сетевые вызовы, завернутые в Observables. Это привело к тому, что некоторые разработчики столкнулись с определенными проблемами при переносе проектов с AngularJS на Angular 2+. Я хочу рассмотреть эти проблемы здесь и описать, почему они вообще могут появляться, рассмотрев типичные различия между Observables и Promises..


Observables — больше возможностей для веб-разработчиков. (рис. медиамодификатор)

Pre-requisites: you should know JS Promises

Observables and Promises — краткое введение

На первый взгляд — Observables — это просто расширенные Promises: Promises выдает одно значение и завершается (разрешается), Observable выдает 0, одно или несколько значений и также завершается (выдача и завершение — это разные действия). Для HTTP-сервиса в AngularJS и Angular предоставляется только одно значение — поэтому кажется, что в этом случае оба фреймворка работают очень похоже.


фрагмент ссылки

И можно подумать, что достаточно просто переименовать $http к this.httpService , тогда к подписываться и все будут счастливы. В очень простых приложениях это даже может работать — но если ваше приложение делает что-то большее, чем «Hello world» — пожалуйста, обратите внимание на эти различия.

# 1 Нетерпеливый против ленивого

Взгляните на пример ниже:


фрагмент ссылки

Когда я звоню Сохранить изменения method — первый пример с запросом, обернутым в промис, будет работать как положено. Но в секундах Пример с Observable-оболочкой ничего не произойдет, потому что Observables ленивая оценка в то время как обещания нетерпеливо оцененный.

Это означает, что Promises не волнует, есть ли у них подписчики, чтобы получить результат или нет. А вот Observables (точнее — cold Observable) будут холодными, только если мы на них подпишемся. В приведенном выше случае вы должны подписаться на Observable, возвращаемый Сохранить изменения функция.

saveChanges(data).subscribe()

Чтобы следить за ним — используйте rxjs-не-игнорируемый-наблюдаемый правило от rxjs-tslint-правила по Николас Джеймисон.

#2 Promises нельзя отменить, а Observables можно отписать

Опять же, начнем с примера, когда при изменении входного текста мы выполняем поиск на бэкэнде:


фрагмент ссылки

В чем здесь недостаток — нельзя отклонить результаты предыдущего запроса, если пользователь продолжает печатать (debounce немного уменьшает эту проблему, но не устраняет ее). И еще одна проблема — возможно состояние гонки (когда более поздний результат запроса будет возвращаться быстрее, чем более ранний — поэтому мы получим некорректный ответ).

Observable может избежать этой проблемы довольно элегантно с переключательКарта оператор:


фрагмент ссылки

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


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


# 3 Нет встроенной логики повтора или повтора для промисов. ‘повторение а также ‘повторить попытку операторы для Observables.

Вы можете реализовать логику повторных попыток с помощью промисов, но это выглядит немного громоздко:


фрагмент ссылки

В то время как тот же код Observables будет намного короче:


фрагмент ссылки

Подробнее о вариантах использования операторов повтора и повторной попытки см. моя статья.

#4 Небольшое количество комбинированных инструментов Promises. Для этого Observables предоставляют широкий спектр операторов.

Для Promises все возможности, которые вы можете комбинировать, следующие:

Обещание.все— ожидание разрешения всех промисов, а затем предоставление массива результатов.

Обещание.гонка— дождитесь, пока одно из промисов будет разрешено, и верните этот результат.


Observables дают очень богатые боеприпасы для создания комбинаций:

объединитьПоследние(наблюдаемый1, наблюдаемый2,…)— ждет, пока любой из наблюдаемых испустит и предоставит массив последних испущенных значений из всех наблюдаемых (результат: [value_obs1, value_obs2,..]). Очень хорошо, если вам нужно обновить страницу новыми данными из нескольких разных источников.

**observable1.pipe(withLatestFrom(observable2) **— для каждого значения из observable1 также укажите последнее выданное значение для observable2 (результат: [value_obs1, value_obs2]).

forkJoin(наблюдаемый1, наблюдаемый2,…) — аналог Promise.all — ждет, пока все Observables будут завершены, а затем выдает массив последних значений из всех наблюдаемых аргументов.

молния (наблюдаемый1, наблюдаемый2,…)— ждет, пока все наблюдаемые аргументы выдадут значения с одним и тем же индексом и предоставят массив выданных значений с одним и тем же индексом (результат: [value_obs1, value_obs2,..]).

**race(observable1, observable2,…) — **возвращает Observable, который отражает первый исходный Observable для испускания элемента.

**merge(observable1, observable2,…) — **подписывается на каждый наблюдаемый аргумент и повторно выдает значения из всех них.

переключатьВсе— если предыдущий Observable не завершен — отменить его и подписаться на новый.

конкат (наблюдаемый1, наблюдаемый2,…)— запускать следующую последовательность Observable только после завершения предыдущей (выдает значения одно за другим после каждого конкретного завершения Observable)

И многое другое(переключательКарта, раздел, если, группа по, окнотак далее)

Вы можете узнать больше об этих операторах здесь:

  1. Научитесь комбинировать последовательности RxJs с интуитивно понятными интерактивными диаграммами.
  2. Официальные документы с примерами
  3. «Практический RxJS для веб-разработки» видеокурс.

# 5 Легко предотвратить состояние гонки с помощью Observable и сложно — с Promises.

Скажем, мы периодически делаем сетевой запрос обновленных данных. Но в некоторых ситуациях более поздний результат запроса возвращается быстрее, чем более ранний — поэтому мы получаем некорректный (более ранний) ответ, отображаемый как последний.


фрагмент ссылки

На этот код может повлиять проблема состояния гонки.

Чтобы предотвратить это с помощью запросов, обернутых в Observable, мы можем использовать concatMap оператор.


фрагмент ссылки

concatMapсделает следующий сетевой вызов только после того, как предыдущий будет сделан и обработан. Конечно, если вам не нужны предыдущие результаты — тогда используйте switchMap (как в первом примере этой статьи).

Вывод

Во время миграции с AngularJS (использует промисы для сетевых вызовов) на Angular 2+ (использует Observable) вы должны знать о возможных различиях промисов и Observable. Надеюсь, моя статья помогла вам прояснить эту тему. Теперь пришло время мигрировать!

Нравится эта статья? Будем на связи Твиттер.

Этот пост изначально был опубликован в ИТНЕКСТ.


Начиная с раздела 4 моего Видеокурс RxJS авансы персонала проверены — так что, если вы уже знакомы с RxJS — вы также можете найти что-то полезное для себя: наблюдаемые объекты более высокого порядка, антипаттерны, планировщики, модульное тестирование и т. д.! Попробуйте !

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *