Какая разница между Promise
и Observable
в Angular?
Пример каждого из них поможет понять оба случая. В каком сценарии мы можем использовать каждый случай?
Какая разница между Promise
и Observable
в Angular?
Пример каждого из них поможет понять оба случая. В каком сценарии мы можем использовать каждый случай?
Ответы:
обещание
Promise
Обрабатывает одно событие , когда завершается асинхронной операции или терпит неудачу.Примечание: есть
Promise
библиотеки, которые поддерживают отмену, но ES6Promise
пока нет.наблюдаемый
An
Observable
подобнаStream
(во многих языках) и позволяет передавать ноль или более событий, когда обратный вызов вызывается для каждого события.Часто
Observable
предпочтительнее,Promise
потому что он предоставляет функцииPromise
и многое другое. ПриObservable
этом не имеет значения, хотите ли вы обрабатывать 0, 1 или несколько событий. Вы можете использовать один и тот же API в каждом случае.Observable
также имеет преимущество передPromise
быть аннулированы . Если результат запроса HTTP на сервер или какой - либо другой операции дорогой асинхронном больше не требуется, тоSubscription
изObservable
позволяет отменить подписку, в то время какPromise
в конечном итоге вызвать успех или сбой обратного вызова , даже если вам не нужно уведомление или результат, который он дает больше.Наблюдаемое предоставляет операторам , как
map
,forEach
,reduce
, ... похожие на массивЕсть также мощные операторы, такие как
retry()
, илиreplay()
, ... которые часто очень удобны.источник
Promise
, наряду сasync
/,await
ваш код снова становится плоским! В большинстве ситуаций и в проектах, которые не имеют отношения к ракетостроению, нет необходимости писать эти ужасные вложенные функции с излишне сложными цепочками методов. Вы можете использоватьasync
/await
сегодня с транспиляторами, напримерTypeScript
, и писать реальный понятный для человека плоский код без всякогоrxjs
шаблона. Вы, вероятно, все еще будете нуждатьсяrxjs
иногда в избранных ситуациях, потому что у этого действительно есть много вещей, чтобы предложить.И то,
Promises
и другоеObservables
предоставляет нам абстракции, которые помогают нам справляться с асинхронной природой наших приложений. Разница между ними была четко указана @ Günter и @Relu.Поскольку фрагмент кода стоит тысячи слов, давайте разберем приведенный ниже пример, чтобы его было проще понять.
Angular использует Rx.js Observables вместо обещаний иметь дело с HTTP.
Предположим, что вы создаете функцию поиска, которая должна мгновенно отображать результаты при вводе. Звучит знакомо, но есть много проблем, которые идут с этой задачей.
HTTP
запросов. По сути, мы хотим нажать на него только после того, как пользователь перестал печатать вместо каждого нажатия клавиши.Демо будет просто состоять из двух файлов:
app.ts
иwikipedia-service.ts
. В сценарии реального мира мы, скорее всего, разделим вещи дальше.Ниже приведена реализация на основе Promise , которая не обрабатывает ни один из описанных крайних случаев.
wikipedia-service.ts
Мы внедряем
Jsonp
сервис дляGET
запроса API-интерфейса Wikipedia с заданным поисковым термином. Обратите внимание, что мы звонимtoPromise
, чтобы получить от аObservable<Response>
доPromise<Response>
. В конце концов, вPromise<Array<string>>
качестве возвращаемого типа нашего метода поиска получим.app.ts
Здесь тоже нет ничего удивительного. Мы внедряем наш
WikipediaService
и выставляем его функциональность через шаблон поиска в шаблон. Шаблон просто привязывается к keyup и звонкамsearch(term.value)
.Мы разворачиваем результат Обещания, который возвращает метод поиска в WikipediaService, и выставляем его в виде простого массива строк в шаблоне, чтобы можно было
*ngFor
выполнить цикл по нему и создать для нас список.Посмотрите пример реализации на основе Promise на Plunker
Где наблюдаемые действительно сияют
Давайте изменим наш код, чтобы не забивать конечную точку при каждом нажатии клавиши, а вместо этого отправлять запрос только тогда, когда пользователь перестал печатать в течение 400 мс
Чтобы раскрыть такие сверхспособности, нам сначала нужно получить выражение
Observable<string>
, содержащее поисковый термин, который вводит пользователь. Вместо ручной привязки к событию keyup мы можем воспользоватьсяformControl
директивой Angular . Чтобы использовать эту директиву, нам сначала нужно импортироватьReactiveFormsModule
в наш модуль приложения.app.ts
После импорта мы можем использовать formControl из нашего шаблона и установить для него имя «term».
В нашем компоненте мы создаем экземпляр
FormControl
from@angular/form
и выставляем его как поле под именем term в нашем компоненте.За кулисами термин автоматически предоставляет
Observable<string>
свойство as, наvalueChanges
которое мы можем подписаться. Теперь, когда у нас естьObservable<string>
, преодоление пользовательского ввода так же просто, как вызовdebounceTime(400)
нашегоObservable
. Это вернет новое значение,Observable<string>
которое будет выдавать новое значение только в том случае, если новые значения не поступали в течение 400 мс.Было бы напрасной тратой ресурсов на отправку еще одного запроса по поисковому запросу, для которого наше приложение уже показывает результаты. Все, что нам нужно сделать для достижения желаемого поведения, это вызвать
distinctUntilChanged
оператора сразу после того, как мыdebounceTime(400)
Смотрите пример реализации Observable на Plunker
Поскольку я использую Http в Angular, я согласен, что в обычных случаях использования нет большой разницы при использовании Observable over Promise. Ни одно из преимуществ на самом деле не актуально здесь на практике. Надеюсь, что я смогу увидеть какой-нибудь продвинутый вариант использования в будущем :)
источник
И Promises, и Observables помогут нам работать с асинхронными функциями в JavaScript. Они очень похожи во многих случаях, однако, между ними все еще есть некоторые различия, обещания - это значения, которые будут разрешаться
asynchronous
такими способами, как http- вызовы. С другой стороны, наблюдаемые имеют дело с последовательностью асинхронных событий . Основные различия между ними перечислены ниже:обещаю:
наблюдаемый:
Кроме того, я создал графическое изображение для вас ниже, чтобы визуально показать различия:
источник
Promise
неправильный способ думать о том, как обещания.Promise
Несет ответственность» , это только к успеху ручки или отказу в совместимом способе асинхронного .. Если вы хотите , чтобы отменить запрос HTTP вы отменить запрос, а не обещание, и сделать результат отмены либо выполнить или отклонить обещание. jsfiddle.net/greggman/ea0yhd4pобещания
Наблюдаемые
Один оператор повторной попытки может быть использован для повторной попытки, когда это необходимо, также, если нам нужно повторить наблюдаемое, основываясь на некоторых условиях, повторная попытка при использовании.
Примечание : список операторов вместе с их интерактивными диаграммами доступен здесь на RxMarbles.com
источник
В ответах отсутствует один недостаток Observables. Обещания позволяют использовать функции ES7 async / await. С их помощью вы можете написать асинхронный код, как если бы это был синхронный вызов функции, поэтому вам больше не нужны обратные вызовы. Единственная возможность для Observables сделать это - преобразовать их в Обещания. Но когда вы конвертируете их в Promises, вы можете снова получить только одно возвращаемое значение:
Дальнейшее чтение: Как я могу «ждать» на Rx Observable?
источник
Обещания и Observables обрабатывают только асинхронный вызов.
Вот различия между ними:
наблюдаемый
обещание
Выдает только одно значение за раз
Звонит в сервисы без .then и .catch
Не может быть отменено
Не предоставляет никаких операторов
источник
Несмотря на то, что этот ответ запоздал, я суммировал различия ниже,
Наблюдаемое:
function
который принимаетan observer
и возвращаетfunction Observer: an object with next, error.
subscribe/unsubscribe
своему потоку данных передавать следующее значение наблюдателю,notify
наблюдателюerrors
и информировать наблюдателя оstream completion
function to handle next value
ошибках и конце потока (события пользовательского интерфейса, ответы http, данные с веб-сокетами).multiple values
временемcancel-able/retry-able
и поддерживает операторов, таких какmap,filter,reduce
и т. Д.Observable.create()
- возвращает Observable, который может вызывать методы -Observer Observable.from()
- преобразует массив или итерируется в -Observable Observable.fromEvent()
- преобразует событие в Observable -Observable.fromPromise()
- преобразует Promise в Observable -Observable.range()
- возвращает последовательность целых чисел в указанном диапазонеОбещание :
Обещание представляет собой задачу, которая закончится в будущем;
Обещания становятся
resolved by a value
;Обещания отклоняются исключениями;
Нет
cancellable
и возвращаетсяa single value
Обещание разоблачить функцию
(then)
-тогда вернет новый
promise
;-позволяет для
attachment
того что будет выполнено на основанииstate
;-
handlers
этоguaranteed
выполнить вorder attached
;источник
Я только что имел дело с проблемой, где Promises были лучшим решением, и я делюсь этим здесь для всех, кто наткнулся на этот вопрос, если он окажется полезным (это был именно тот ответ, который я искал ранее):
В проекте Angular2 у меня есть служба, которая принимает некоторые параметры и возвращает список значений для заполнения выпадающих меню на форме. Когда компонент формы инициализируется, мне нужно вызывать одну и ту же службу несколько раз с разными параметрами, чтобы определить ряд различных раскрывающихся меню, однако, если я просто поставлю в очередь все переменные для вызова службы, только последняя успешно завершится, а остальная ошибка вне. Служба, извлекаемая из базы данных, может обрабатывать только один запрос за раз.
Единственный способ успешно заполнить все переменные выпадающего меню - это вызвать службу таким образом, чтобы предотвратить обработку нового запроса до тех пор, пока последний запрос не будет завершен, и механизм Promise / .then хорошо решил проблему.
Я определил функции в компоненте, а затем вызвал initializeDropDowns () в ngOnInit.
Функция fetchValueList возвращает Promise, поэтому первый вызов передает первый listCode, и когда Promise разрешается, возвращаемое значение находится в переменной данных в блоке .then, где мы можем присвоить его переменной this.firstValList. Поскольку функция вернула данные, мы знаем, что служба завершена, и ее можно снова вызвать с помощью второго listCode, возвращаемое значение находится в переменной data в следующем блоке .then, и мы присваиваем его переменной this.secondValList.
Мы можем связать это столько раз, сколько требуется, чтобы заполнить все переменные, и в последнем блоке кода мы просто опускаем оператор return, и блок завершается.
Это очень специфический случай использования, когда у нас есть один сервис, который должен вызываться несколько раз при инициализации компонента, и когда сервис должен завершить выборку и вернуть значение, прежде чем он будет вызван снова, но в этом случае, Метод Promise / .then был идеальным.
источник
scan()
для создания потока последовательных наблюдаемых. Тем не менее, ваш подход может быть более явным и более простым для понимания.Я считаю, что все остальные ответы должны очистить ваши сомнения. Тем не менее, я просто хотел добавить, что наблюдаемые основаны на функциональном программировании, и я нахожу очень полезными функции, которые идут вместе с ним, такие как map, flatmap, lower, zip. Согласованность, которую обеспечивает сеть, особенно когда она зависит от запросов API, является серьезным улучшением.
Я настоятельно рекомендую эту документацию , поскольку это официальная документация о реактиве X, и я считаю ее наиболее понятной.
Если вы хотите получить доступ к наблюдаемым, я бы предложил этот пост из трех частей: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
Хотя он предназначен для RxJava, концепции те же, и это действительно хорошо объяснено. В документации по реактиву у вас есть эквиваленты для каждой функции. Вы должны искать RxJS.
источник
Promise:
Наблюдаемое:
При желании вы можете использовать обещания вместо наблюдаемых при вызове HTTP в Angular.
источник
Обзор:
Вы всегда можете использовать наблюдаемое для работы с асинхронным поведением, так как наблюдаемое обладает всеми функциями, которые предлагает обещание (+ дополнительно). Однако иногда эта дополнительная функциональность, которую предлагают Observables, не нужна. Тогда было бы лишними издержками импортировать библиотеку, чтобы она могла их использовать.
Когда использовать Обещания:
Используйте обещания, когда у вас есть одна асинхронная операция, для которой вы хотите обработать результат. Например:
Таким образом, обещание выполняет некоторый код, где оно либо разрешает, либо отклоняет. Если резолвить или отклонить называются обещание переходит из отложенного состояния либо в разрешенном или отвергнуто государство. Когда состояние обещания разрешается,
then()
вызывается метод. Когда состояние обещания отклоняется,catch()
вызывается метод.Когда использовать Observables:
Используйте Observables, когда есть поток (данных) с течением времени, который вам нужно обработать. Поток - это последовательность элементов данных, которые становятся доступными с течением времени . Примеры потоков:
В самой Наблюдаемой задается, когда произошло следующее событие , когда произошла ошибка , или когда Наблюдаемая завершена . Затем мы можем подписаться на эту наблюдаемую, которая активирует ее, и в этой подписке мы можем передать 3 обратных вызова (не всегда нужно передавать все). Один обратный вызов для выполнения, один обратный вызов для ошибки и один обратный вызов для завершения. Например:
При создании наблюдаемой требуется функция обратного вызова, которая предоставляет наблюдателя в качестве аргумента. На этом наблюдатель, то вы можете позвонить
onNext
,onCompleted
,onError
. Затем, когда Observable подписан на него, он вызывает соответствующие обратные вызовы, переданные в подписку.источник
Обещание - предоставить единую будущую стоимость. Не ленивый . Не отменяется. Он либо отклонит, либо разрешит.
Наблюдаемый - Обеспечьте многократную будущую ценность. Ленивый Отмена в состоянии. Предоставляют другие методы живой карты, фильтруют, уменьшают.
источник
Обещание против наблюдаемого сходства в первую очередь
Наблюдаемый пример сейчас. Здесь также мы передаем функцию наблюдаемому, наблюдателю для обработки асинхронной задачи. В отличие от решимости в обещании, он имеет следующий метод и подписывается вместо.
Таким образом, обе обрабатывают асинхронные задачи. Теперь посмотрим на разницу.
Обещание против наблюдаемой разницы
обещание
наблюдаемый
источник
Below are some important differences in promises & Observables.
источник
Обещание генерирует одно событие, когда асинхронное действие завершается или завершается неудачей.
Observable похож на Stream (на многих языках) и позволяет передавать по крайней мере ноль или более событий, когда обратный вызов требуется для каждого события.
Часто наблюдаемый предпочтительнее Обещания, поскольку он дает основные моменты Обещания и многое другое. С Observable не имеет значения, нужно ли вам обрабатывать 0, 1 или различные события. Вы можете использовать аналогичный API для каждого случая.
Обещание: обещание испускает одно значение
Например:
Наблюдаемый: излучает несколько значений за период времени
Например:
мы можем думать о наблюдаемой как о потоке, который генерирует множество значений в течение определенного периода времени, и для каждого испускаемого элемента вызывается одна и та же функция обратного вызова, поэтому с помощью наблюдаемой мы можем использовать один и тот же API для обработки асинхронных данных. передаются ли эти данные в виде одного или нескольких значений в течение некоторого отрезка времени.
Promise:
Наблюдаемое:
Угловые обещания против наблюдаемых
источник
Promise выдает одно значение, а Observable - несколько значений. Таким образом, при обработке HTTP-запроса Promise может управлять одним ответом на один и тот же запрос, но что, если на один и тот же запрос существует несколько ответов, мы должны использовать Observable. Да, Observable может обрабатывать несколько ответов на один и тот же запрос.
обещание
Вывод
наблюдаемый
Вывод
источник
обещание
наблюдаемый
Для лучшего понимания обратитесь к https://stackblitz.com/edit/observable-vs-promises.
источник
Я вижу, что многие люди используют аргумент, что Observable являются «отменяемыми», но довольно просто сделать Promise «отменяемыми»
источник
Короткий ответ :
Наблюдаемый является лучше , она имеет все Обещания функции плюс дополнительные функции.
Длинный ответ:
Обещания:
Наблюдаемое:
источник
Хотя принятый ответ в целом хорош, я не думаю, что он подчеркивает, что при работе с угловыми компонентами вы почти всегда хотите использовать Observable, потому что он поддерживает отмену. Обещания не могут быть отменены и будут выполнены, даже если ваш компонент уничтожен. Angular имеет тенденцию прощать, пока это не так.
Например, любое обнаружение изменений вручную на уничтоженном компоненте вызовет исключение:
Если ваш компонент уничтожен до выполнения обещания, вы получите
attempt to use destroyed view
об ошибке, когда обещание будет выполнено.В качестве альтернативы, если вы используете наблюдаемые с takeUntil шаблоном , то, как только ваш компонент будет уничтожен, подписка будет отменена.
Это немного надуманный пример, но выполнение кода для уничтоженного компонента, вероятно, приведет к ошибкам. Если вы действительно не хотите делать это по какой-то причине: p
источник
Что-то, с чем я столкнулся, не было очевидно из первого прочтения учебника, и в документации была идея многоадресной рассылки.
Убедитесь, что вы знаете, что по умолчанию несколько подписок инициируют несколько выполнений в Observable. Несколько подписок на один HTTP-вызов Observable вызовет несколько идентичных HTTP-вызовов, если вы не
.share()
включите многоадресную рассылку.Обещание заставляет вас иметь дело с одной вещью за раз, разворачивать ее данные, обрабатывать исключения, имеет языковую поддержку для таких классных вещей, как async / await, а в остальном довольно просто.
Обсерватория имеет много наворотов, но вам нужно понимать силу, с которой вы работаете, иначе ее можно использовать не по назначению.
источник
Promise:
Async Event Handler - объект Promise представляет возможное завершение (или сбой) асинхронной операции и ее результирующее значение.
Синтаксис: новый Promise (исполнитель);
Например:
Об обещании: него есть один конвейер, поэтому он будет возвращать значения только один раз при вызове. его односторонний обработчик, поэтому однажды вызванный вы не сможете отменить. полезный синтаксис вы можете поиграть, когда (), а затем ()
Наблюдаемые:
Observables - это ленивые коллекции нескольких значений с течением времени. это действительно отличный подход для асинхронных операций. это можно сделать с помощью rxjs, который поддерживает кроссплатформенность, может использовать angular / реагировать и т. д.
его действие как лайнер потока. может быть много трубопроводным. поэтому после определения вы можете подписаться на получение результатов во многих местах.
Синтаксис:
import * as Rx from "@reactivex/rxjs";
для инициации:так далее
подписываться:
RxLogger.getInstance();
Например:
так как он поддерживает несколько конвейеров, вы можете подписать результат в другом месте, у него гораздо больше возможностей, чем обещаний.
Использование: это имеет больше возможностей, таких как
map, filter, pipe, map, concatMap etc
источник
Основное различие между наблюдаемым и обещаниями:
источник
Наблюдаемые часто сравнивают с обещаниями. Вот некоторые ключевые отличия:
Наблюдаемые являются декларативными; расчет не начинается до подписки. Обещания выполняются немедленно при создании. Это делает наблюдаемые полезными для определения рецептов, которые можно запускать, когда вам нужен результат.
Наблюдаемые дают много значений. Обещания дают один. Это делает наблюдаемые полезными для получения нескольких значений с течением времени.
Наблюдаемые различают цепочку и подписку. Обещания имеют только предложения .then (). Это делает наблюдаемые полезными для создания сложных рецептов преобразования, которые будут использоваться другими частями системы, без необходимости выполнения работы.
Observables subscribe () отвечает за обработку ошибок. Обещания подталкивают к ошибкам ребенка. Это делает наблюдаемые полезными для централизованной и предсказуемой обработки ошибок.
Это самое простое отличие, которое вы можете найти в документах ANGULAR.IO. остальное ответ дается большинством правильно на своем месте
источник
Обещания ориентированы только на отдельные значения или решают, наблюдаемые являются потоком данных.
Наблюдаемые могут быть отменены, но обещания не могут быть отменены.
Наименее известный, по крайней мере для меня
источник
поток значений (от 0 до нескольких значений),
источник
Observables и Promises помогают нам работать с асинхронными функциями в JavaScript / typcript. Они очень похожи во многих случаях, однако между ними все еще есть некоторые различия.
источник
На эту тему уже есть много ответов, поэтому я бы не стал добавлять лишний.
Но тому, кто только начал изучать Observable / Angular и задается вопросом, какой из них использовать, сравните с Promise , я бы порекомендовал вам сохранить все Observable и преобразовать все существующие обещания в вашем проекте в Observable.
Просто потому, что сама структура Angular и ее сообщество используют Observable. Поэтому было бы полезно, когда вы интегрируете сервисы фреймворка или сторонние модули и объединяете все воедино.
Хотя я ценю все отрицательные отзывы, но я все же настаиваю на своем мнении выше, если кто-то не оставит надлежащий комментарий, чтобы перечислить несколько сценариев, которые все еще могут быть полезны в вашем Angular проекте для использования Promises over Observables.
Конечно, ни одно мнение не является на 100% правильным во всех случаях, но, по крайней мере, я думаю, что 98% времени для обычных коммерческих проектов, реализованных в Angular Framework, Observable - верный путь.
Даже если вам не понравится в начале вашего простого хобби-проекта, вы скоро поймете, что почти все компоненты, с которыми вы взаимодействуете в Angular, и большинство дружественных для Angular сторонних фреймворков используют Observables, а затем вы в конечном итоге постоянно преобразовывал ваше Обещание в Observable, чтобы общаться с ними.
Эти компоненты включают, но не ограничиваются: HttpClient, построитель форм, модули / диалоги угловых материалов, хранилище / эффекты Ngrx и ngx-bootstrap.
Фактически, единственное обещание от угловой системы, с которым я имел дело в последние 2 года, - это
APP_INITIALIZER
.источник