В чем разница между обещаниями и наблюдаемыми?

Может кто-нибудь объяснить, пожалуйста, разницу между Promise и Observable в Angular?

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

Ответ 1

Promise

A Promise обрабатывает одно событие, когда операция async завершается или завершается с ошибкой.

Примечание. Существуют библиотеки Promise, которые поддерживают отмену, но ES6 Promise пока не работает.

Наблюдаемые

An Observable похож на Stream (на многих языках) и позволяет пропускать ноль или более событий, где обратный вызов вызывается для каждого события.

Часто Observable предпочтительнее Promise, поскольку он предоставляет функции Promise и более. С Observable не имеет значения, хотите ли вы обрабатывать 0, 1 или несколько событий. Вы можете использовать один и тот же API в каждом случае.

Observable также имеет преимущество перед Promise быть отменено. Если результат HTTP-запроса на сервер или какая-либо другая дорогостоящая операция async больше не требуется, Subscription Observable позволяет отменить подписку, а Promise в конечном итоге вызовет успешный или неудачный обратный вызов даже если вам не требуется уведомление или результат, который он предоставляет больше.

Observable предоставляет операторы, такие как map, forEach, reduce,... похожие на массив

Существуют также мощные операторы, такие как retry() или replay(),... которые часто весьма удобны.

Ответ 2

И Promises и Observables предоставляют нам абстракции, которые помогают нам справляться с асинхронной природой наших приложений. Разница между ними была четко указана @Günter и @Relu.

Поскольку фрагмент кода стоит тысячи слов, давайте разберем приведенный ниже пример, чтобы его было проще понять.

Спасибо @Christoph Burgdorf за отличную статью


Angular использует Rx.js Observables вместо обещаний иметь дело с HTTP.

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

  • Мы не хотим попадать на конечную точку сервера каждый раз, когда пользователь нажимает клавишу, он должен заполнить их потоком HTTP запросов. По сути, мы хотим нажать на него только после того, как пользователь перестал печатать вместо каждого нажатия клавиши.
  • Не нажимайте конечную точку поиска с теми же параметрами запроса для последующих запросов.
  • Разберитесь с неправильными ответами. Когда у нас есть несколько запросов одновременно, мы должны учитывать случаи, когда они возвращаются в неожиданном порядке. Представьте, что мы сначала печатаем компьютер, останавливаемся, запрос отправляется, мы набираем машину, останавливаем запрос отправляем. Теперь у нас есть два запроса в полете. К сожалению, запрос, который несет результаты для компьютера, возвращается после запроса, который несет результаты для автомобиля.

Демо будет просто состоять из двух файлов: app.ts и wikipedia-service.ts. В реальном сценарии мы, скорее всего, разбили бы вещи дальше.


Ниже приведена реализация на основе Promise, которая не обрабатывает ни один из описанных крайних случаев.

wikipedia-service.ts

import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';

@Injectable()
export class WikipediaService {
  constructor(private jsonp: Jsonp) {}

  search (term: string) {
    var search = new URLSearchParams()
    search.set('action', 'opensearch');
    search.set('search', term);
    search.set('format', 'json');
    return this.jsonp
                .get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
                .toPromise()
                .then((response) => response.json()[1]);
  }
}

Мы Jsonp сервис Jsonp для выполнения запроса GET к API Википедии с заданным поисковым термином. Обратите внимание, что мы вызываем toPromise, чтобы перейти от Observable<Response> к Promise<Response>. В конечном итоге Promise<Array<string>> в качестве возвращаемого типа нашего метода поиска.

app.ts

// check the plnkr for the full list of imports
import {...} from '...';

@Component({
  selector: 'my-app',
  template: '
    <div>
      <h2>Wikipedia Search</h2>
      <input #term type="text" (keyup)="search(term.value)">
      <ul>
        <li *ngFor="let item of items">{{item}}</li>
      </ul>
    </div>
  '
})
export class AppComponent {
  items: Array<string>;

  constructor(private wikipediaService: WikipediaService) {}

  search(term) {
    this.wikipediaService.search(term)
                         .then(items => this.items = items);
  }
}

Здесь тоже нет ничего удивительного. Мы внедряем наш WikipediaService и выставляем его функциональность через шаблон поиска в шаблон. Шаблон просто привязывается к keyup и вызывает search(term.value).

Мы разворачиваем результат Обещания, который возвращает метод поиска WikipediaService, и выставляем его в виде простого массива строк в шаблон, чтобы мы могли через него *ngFor цикл *ngFor и создать для нас список.

Посмотрите пример реализации на основе Promise на Plunker


Где наблюдаемые действительно сияют

Давайте изменим наш код, чтобы не забивать конечную точку при каждом нажатии клавиши, а вместо этого отправлять запрос только тогда, когда пользователь перестал печатать в течение 400 мс

Чтобы раскрыть такие сверхспособности, нам сначала нужно получить Observable<string> которая содержит поисковый термин, который вводит пользователь. Вместо ручной привязки к событию keyup мы можем воспользоваться директивой Angulars formControl. Чтобы использовать эту директиву, нам сначала нужно импортировать ReactiveFormsModule в наш модуль приложения.

app.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

После импорта мы можем использовать formControl из нашего шаблона и установить для него имя "term".

<input type="text" [formControl]="term"/>

В нашем компоненте мы создаем экземпляр FormControl из @angular/form и выставляем его как поле под термином имени в нашем компоненте.

За кулисами термин автоматически выставляет Observable<string> как свойство valueChanges которое мы можем подписаться. Теперь, когда у нас есть Observable<string>, преодоление пользовательского ввода так же просто, как и вызов debounceTime(400) для нашего Observable. Это вернет новый Observable<string> который будет выдавать новое значение только тогда, когда новые значения не поступали в течение 400 мс.

export class App {
  items: Array<string>;
  term = new FormControl();
  constructor(private wikipediaService: WikipediaService) {
    this.term.valueChanges
              .debounceTime(400)        // wait for 400ms pause in events
              .distinctUntilChanged()   // ignore if next search term is same as previous
              .subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
  }
}

Было бы напрасной тратой ресурсов на отправку еще одного запроса по поисковому запросу, для которого наше приложение уже показывает результаты. Все, что нам нужно сделать, чтобы добиться желаемого поведения, чтобы вызвать distinctUntilChanged оператора сразу после мы назвали debounceTime(400)

Смотрите пример реализации Observable на Plunker

Чтобы разобраться с нестандартными ответами, ознакомьтесь с полной статьей http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html.

Насколько я использую Http в Angular, я согласен, что в обычных случаях использования нет большой разницы при использовании Observable over Promise. Ни одно из преимуществ на самом деле не актуально здесь на практике. Надеюсь, что в будущем я смогу увидеть передовые варианты использования :)


Учить больше

Ответ 3

Обе Promises и Observables помогут нам работать с асинхронными функциями в JavaScript. Во многих случаях они очень похожи, однако между ними все еще есть некоторые различия, обещания - это значения, которые будут разрешаться в asynchronous способами, такими как http вызовы. С другой стороны, наблюдаемые имеют дело с последовательностью асинхронных событий. Основные различия между ними перечислены ниже:

Обещание:

  • с одним конвейером
  • обычно используется только с асинхронным возвратом данных
  • не легко отменить

наблюдаемый:

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

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

Promises and Observables image

Ответ 4

! Promises vs Наблюдаемые

  • обещание:
    • возвращает одно значение
    • не отменяется
    • более читаемый код с try/catch и async/await
  • наблюдаемым
    • работает с несколькими значениями с течением времени
    • сократимое
    • поддерживает отображение, фильтр, сокращение и аналогичные операторы
    • использовать реактивные расширения (RxJS)
    • массив, элементы которого поступают асинхронно со временем

Ответ 5

обещания

  1. Определение: Помогает запускать функции асинхронно, и использовать их возвращаемые значения (или исключения), но только один раз, когда выполняется.
  2. Не ленивый
  3. Не подлежит отмене (есть библиотеки Promise, которые поддерживают отмену, но ES6 Promise пока не поддерживает). Два возможных решения
    • отклонять
    • Разрешить
  4. Невозможно повторить (Promises должен иметь доступ к исходной функции, которая вернула обещание с возможностью повторной попытки, что является плохой практикой)

Наблюдаемые

  1. Определение: Помогает вам выполнять функции асинхронно и использовать их возвращаемые значения в непрерывной последовательности (несколько раз) при выполнении.
  2. По умолчанию это Lazy, так как он генерирует значения по ходу времени.
  3. Имеет много операторов, что упрощает кодирование.
  4. Один оператор повторной попытки может быть использован для повторной попытки, когда это необходимо, также, если нам нужно повторить наблюдаемое, основываясь на некоторых условиях, повторная попытка при использовании.

    Примечание: список операторов вместе с их интерактивными диаграммами доступен здесь на RxMarbles.com

Ответ 6

В ответах есть недостаток Observables. Promises позволяют использовать функции async/wait ES7. С их помощью вы можете написать асинхронный код, так как это будет синхронный вызов функции, поэтому вам больше не нужны обратные вызовы. Единственная возможность для Observables сделать это - преобразовать их в Promises. Но когда вы конвертируете их в Promises, вы можете вернуть только одно возвращаемое значение:

async function getData(){
    const data = await observable.first().toPromise();
    //do stuff with 'data' (no callback function needed)
}

Дальнейшее чтение: Как я могу "ждать" на наблюдаемом Rx?

Ответ 7

Обещания и Observables обрабатывают только асинхронный вызов.

Вот различия между ними:

наблюдаемый

  1. Выдает несколько значений за период времени
  2. Не вызывается, пока мы не подпишемся на Observable
  3. Можно отменить с помощью метода unsubscribe()
  4. Предоставляет карту, forEach, фильтрует, уменьшает, повторяет и повторяет, когда операторы

обещание

  1. Выдает только одно значение за раз

  2. Звонит в сервисы без .then и .catch

  3. Не может быть отменено

  4. Не предоставляет никаких операторов

Ответ 8

Несмотря на то, что этот ответ задерживается, я подвел итоги ниже,

Наблюдаемые

  • Наблюдаемый - это просто function, который принимает an observer и возвращает function Observer: an object with next, error.
  • Наблюдатель позволяет subscribe/unsubscribe передавать свой поток данных, испускать следующее значение наблюдателю, notify наблюдателя о errors и сообщите наблюдателю о stream completion
  • Наблюдатель предоставляет function to handle next value, ошибки и конец потока (события ui, ответы HTTP, данные с веб-сокетами).
  • Работает с multiple values со временем
  • Это cancel-able/retry-able и поддерживает такие операторы, как map,filter,reduce и т.д.
  • Создание наблюдаемого может быть - Observable.create() - возвращает Observable, который может ссылаться на методы на - Observer Observable.from() - преобразует массив или итерабельность в - Observable Observable.fromEvent() - преобразует событие в Observable - Observable.fromPromise() - преобразует обещание в наблюдаемое - Observable.range() - возвращает последовательность целых чисел в заданном диапазоне

Promise

  • Обещание представляет собой задачу, которая будет завершена в будущем;

  • Promises стать resolved by a value;

  • Promises отклоняются исключениями;

  • Не cancellable, и он возвращает a single value

  • Обещают выставить функцию (then)

    - затем возвращает новый promise;

    -волны для attachment, которые будут выполняться на основе state;

    - handlers - guaranteed для выполнения в order attached;

Ответ 9

Я считаю, что все остальные ответы должны очистить ваши сомнения. Тем не менее, я просто хотел добавить, что наблюдаемые основаны на функциональном программировании, и я нахожу очень полезными функции, которые идут вместе с ним, такие как map, flatmap, lower, zip. Непротиворечивость, достигаемая в Интернете, особенно когда это зависит от запросов API, является серьезным улучшением.

Я настоятельно рекомендую эту документацию, поскольку это официальная документация о реактиве X, и я считаю ее наиболее понятной.

Если вы хотите попасть в наблюдаемые, я бы предложил этот пост из трех частей: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

Хотя это означало для RxJava, понятия те же, и это действительно хорошо объяснено. В документации по реактиву у вас есть эквиваленты для каждой функции. Вы должны искать RxJS.

Ответ 10

Я только что имел дело с проблемой, где Promises были лучшим решением, и я делюсь этим здесь для всех, кто наткнулся на этот вопрос, если он окажется полезным (это был именно тот ответ, который я искал ранее):

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

Единственный способ успешно заполнить все переменные выпадающего меню - это вызвать службу так, чтобы новый запрос не обрабатывался до тех пор, пока последний запрос не был завершен, и механизм Promise/.then прекрасно решил эту проблему.

  fetchValueList(listCode): Promise<any> {
      return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
          .map(response => response.json())
          .toPromise();
  }

  initializeDropDowns() {
      this.fetchValueList('First-Val-List')
          .then(data => {
              this.firstValList = data;
              return this.fetchValueList('Second-Val-List')
          }).then(data => {
              this.secondValList = data;
              return this.fetchValueList('Third-Val-List')
          }).then(data => {
              this.thirdValList = data;
          })  }

Я определил функции в компоненте, а затем вызвал initializeDropDowns() в ngOnInit.

Функция fetchValueList возвращает Promise, поэтому первый вызов передает первый listCode, и когда Promise разрешается, возвращаемое значение находится в переменной данных в блоке.then, где мы можем присвоить его переменной this.firstValList. Поскольку функция вернула данные, мы знаем, что служба завершена, и ее можно снова вызвать с помощью второго listCode, возвращаемое значение находится в переменной data в следующем блоке.then, и мы присваиваем его переменной this.secondValList.

Мы можем связать это столько раз, сколько требуется, чтобы заполнить все переменные, и в последнем блоке кода мы просто опускаем оператор return, и блок завершается.

Это очень специфический случай использования, когда у нас есть один сервис, который должен вызываться несколько раз при инициализации компонента, и когда сервис должен завершить выборку и вернуть значение, прежде чем его можно будет вызвать снова, но в этом случае, Метод Promise/.then был идеальным.

Ответ 11

Promise:

  • Укажите одно будущее значение;
  • Не ленивый;
  • Не отменяется;

Наблюдаемые

  • Выдает несколько значений с течением времени;
  • Ленивый;
  • Cancellable;
  • Поддержка карт, фильтров, сокращений и подобных операторов

Вы можете использовать promises вместо наблюдаемых при вызове HTTP в Angular, если хотите.

Ответ 12

Наблюдаемые против обещаний

Обещания и Observables, оба они предоставляют нам простой способ, который помогает нам бороться с попытками асинхронного характера наших приложений. Однако между ними есть важные различия:

  • Наблюдаемые объекты могут определять аспекты настройки и устранения асинхронного поведения.
  • Наблюдаемые являются отменяемыми.
  • Более того, Observables можно повторить с помощью одного из операторов повторов, предоставляемых API, таких как retry и retryWhen. С другой стороны, Promises требует, чтобы вызывающая сторона имела доступ к исходной функции, которая возвратила обещание, чтобы иметь возможность повторных попыток.

Обещания фактически навязывают эту семантику. Вы можете создать Обещание, которое разрешается с некоторым значением:

const numberPromise = new Promise((resolve) => {
    resolve(5);
});

numberPromise.then(value => console.log(value));
// will simply print 5

Но попытка разрешить Обещание снова с другим значением потерпит неудачу. Обещание всегда разрешается с первым значением, переданным функции разрешения, и игнорирует дальнейшие вызовы к нему:

const numberPromise = new Promise((resolve) => {
    resolve(5);
    resolve(10);
});

numberPromise.then(value => console.log(value));
// still prints only 5

Напротив, Observables позволяют вам разрешать (или, как мы говорим, "излучать") несколько значений. Вот как это будет выглядеть:

const numberObservable = new Observable((observer) => {
    observer.next(5);
    observer.next(10);
});

numberObservable.subscribe(value => console.log(value));
// prints 5 and 10

Заметьте, насколько похож синтаксис - мы переключили Promise на Observable, заменили функцию разрешения на вызов наблюдаем.next и вместо этого использовали подписку, которая ведет себя очень похоже.

Ответ 13

Обзор:

  • И Promises, и Observables помогают нам справляться с асинхронными операциями. Они могут вызывать определенные обратные вызовы после выполнения этих асинхронных операций.
  • Обещание может обрабатывать только одно событие, Observables предназначены для потоков событий с течением времени.
  • Обещания не могут быть отменены, как только они ожидают
  • Данные Observables Emit могут быть преобразованы с помощью операторов

Вы всегда можете использовать наблюдаемое для работы с асинхронным поведением, так как наблюдаемое обладает всеми функциями, которые предлагает обещание (+ дополнительно). Однако иногда эта дополнительная функциональность, которую предлагают Observables, не нужна. Тогда было бы лишними издержками импортировать библиотеку, чтобы она могла их использовать.

Когда использовать обещания:

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

var promise = new Promise((resolve, reject) => {
  // do something once, possibly async
  // code inside the Promise constructor callback is getting executed synchronously

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

//after the promise is resolved or rejected we can call .then or .catch method on it

promise.then((val) => console.log(val))      // logs the resolve argument
       .catch((val) => console.log(val));    // logs the reject argument

Таким образом, обещание выполняет некоторый код, где оно либо разрешает, либо отклоняет. Если вызывается либо разрешение, либо отклонение, обещание переходит из состояния ожидания в состояние разрешения или отклонения. Когда состояние обещания разрешается, вызывается метод then(). Когда состояние обещания отклоняется, вызывается метод catch().

Когда использовать Observables:

Используйте Observables, когда существует поток (данных) с течением времени, который вам нужно обработать. Поток - это последовательность элементов данных, которые становятся доступными с течением времени. Примеры потоков:

  1. Пользовательские события, например, щелчки или нажатия клавиш. Пользователь генерирует события (данные) с течением времени.
  2. Websockets: после того, как клиент установил соединение WebSocket с сервером, он со временем передает данные.

В самой Наблюдаемой задается, когда произошло следующее событие, когда произошла ошибка, или когда Наблюдаемая завершена. Затем мы можем подписаться на эту наблюдаемую, которая активирует ее, и в этой подписке мы можем передать 3 обратных вызова (не всегда нужно передавать все). Один обратный вызов для выполнения, один обратный вызов для ошибки и один обратный вызов для завершения. Например:

const observable = Rx.Observable.create(observer => {
  // create a single value and complete
  observer.onNext(1);
  observer.onCompleted();
});

source.subscribe(
  x => console.log('onNext: %s', x),   //  success callback
  e => console.log('onError: %s', e),  //  error callback
  () => console.log('onCompleted')     //  completion callback
 );

// first we log: onNext: 1
//  then we log: onCompleted

При создании наблюдаемой требуется функция обратного вызова, которая предоставляет наблюдателя в качестве аргумента. В этом случае вы можете вызвать onNext, onCompleted, onError. Затем, когда Observable подписан на него, он вызывает соответствующие обратные вызовы, переданные в подписку.

Ответ 14

Обещание - укажите единую будущую стоимость. Не ленивый. Не отменяется. Он либо отклонит, либо разрешит.

Наблюдаемый - Обеспечьте многократную будущую ценность. Ленивый Отмена в состоянии. Предоставляют другие методы живой карты, фильтруют, уменьшают.

Ответ 15

Observables и Promises предоставляют средства для работы с асинхронными действиями в JavaScript. В то время как Promises либо отклоняет/разрешает на основе завершения одного асинхронного события (http-запрос), Observables может непрерывно генерировать изменения в состоянии на основе наблюдателей, которые подписываются на них.

Одно из основных различий между ними заключается в том, что наблюдаемые предоставляют способы отменить запрос и отправить новый. Где, как обещают, не позволяют такую функцию.

Кроме того, Promise выдает одно значение, а Observable - несколько значений. Таким образом, при обработке HTTP-запроса Promise может управлять одним ответом на один и тот же запрос, но что, если на один и тот же запрос существует несколько ответов, мы должны использовать Observable.

Ответ 16

И Promises, и Observables помогают нам справляться с асинхронными операциями. Они могут вызывать определенные обратные вызовы после выполнения этих асинхронных операций.

Angular использует Observables из RxJS вместо обещаний иметь дело с HTTP

Below are some important differences in promises & Observables.

difference between Promises and Observables

Ответ 17

Обещание против наблюдаемого сходства в первую очередь

  1. Оба использовали для обработки асинхронного кода.
  2. Пожалуйста, посмотрите на пример обещания. Конструктор Promise передает справочную функцию разрешения, которая будет вызываться при вызове с некоторым значением после выполнения некоторой асинхронной задачи.

const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve("Hello from a Promise!");
  }, 2000);
});

promise.then(value => console.log(value));

  1. Наблюдаемый пример сейчас. Здесь также мы передаем функцию наблюдаемому, наблюдателю для обработки асинхронной задачи. В отличие от решимости в обещании он имеет следующий метод и подписывается вместо.

  2. Таким образом, оба обрабатывают асинхронные задачи. Теперь давайте посмотрим на разницу.


const observable = new Observable(observer => {
  setTimeout(() => {
    observer.next('Hello from a Observable!');
  }, 2000);
});

observable.subscribe(value => console.log(value));

Обещание против наблюдаемой разницы

обещание

  1. Он разрешает или отклоняет одно значение и может одновременно обрабатывать одно значение асинхронной задачи.
  2. Обещание, однажды решившее асинхронное значение, которое оно завершает, больше не может быть использовано. Это только одноразовое использование, и здесь оно не выполняется.
  3. Не подлежит отмене
  4. Нет поддержки rxjs для операторов.

наблюдаемый

  1. способность выдавать несколько асинхронных значений.
  2. Используется для обработки потока событий или значений. Предположим, у вас есть массив из множества задач или значений, и вы хотите, чтобы каждый раз, когда значение вставлялось в него, оно должно обрабатываться автоматически. Каждый раз, когда вы помещаете значение в этот массив, все его подписчики получат последнее значение автоматически.
  3. Observables полезны для наблюдения изменений входных данных, повторяющихся интервалов, широковещательных значений для всех дочерних компонентов, push-уведомлений веб-сокетов и т.д.
  4. Может быть отменено с помощью метода отписки в любое время.
  5. Еще одна хорошая новость, которая обещает поддержку операторов rxjs. У вас есть много операторов конвейера, в основном, отображающих, фильтрующих, switchMap, Объединение последних и т.д. Для преобразования наблюдаемых данных перед подпиской.

enter image description here


Ответ 18

Ниже приведены некоторые важные различия в обещаниях и наблюдаемых.

обещание

  • Выдает только одно значение
  • Не подлежит отмене
  • Не подлежит разделению
  • Всегда асинхронный

наблюдаемый

  • Выдает несколько значений
  • Выполняется только когда он вызывается или кто-то подписывается
  • Может быть отменено
  • Может быть разделено и подписано этим общим значением несколькими подписчиками. И все подписчики выполнят в один момент времени.
  • возможно асинхронный

Для лучшего понимания обратитесь к https://stackblitz.com/edit/observable-vs-promises.

Ответ 19

Я вижу, что многие люди используют аргумент, что Observable являются "отменяемыми", но довольно просто сделать Promise "отменяемыми"

function cancellablePromise(body) {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res; reject = rej;
    body(resolve, reject)
  })
  promise.resolve = resolve;
  promise.reject = reject;
  return promise
}

// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('10', 100))
})

p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console

// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('blop'), 100)
})

p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200

Ответ 20

Короткий ответ :

Наблюдаемый лучше, он имеет все функции Обещаний плюс дополнительные функции.


Длинный ответ:

Обещания:

  • Одноразовое использование "Вернуть данные один раз"
  • Нет отмены
  • Один слушатель
  • Нет поддержки сокета один слушатель

Наблюдаемое:

  • Возвращать данные много раз при изменении данных
  • Поддержка отмены
  • Гнездо поддержки
  • Поддержка многих слушателей и уведомлять их при изменении данных
  • Поддержка карты, фильтрация, уменьшение

Ответ 21

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

Например, любое обнаружение изменений вручную на уничтоженном компоненте вызовет исключение:

ngOnInit() {
  // promise api
  this.service.getData().then(d => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });

  // observable api
  this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });
}

Если ваш компонент уничтожен до разрешения обещания, вы получите attempt to use destroyed view ошибку attempt to use destroyed view при разрешении обещания.

В качестве альтернативы, если вы используете наблюдаемые с шаблоном takeUntil, то, как только ваш компонент будет уничтожен, подписка будет отменена.

Это немного надуманный пример, но выполнение кода для уничтоженного компонента, вероятно, приведет к ошибкам. Если вы действительно не хотите делать это по какой-то причине: p

Ответ 22

Что-то, с чем я столкнулся, не было очевидно из первого прочтения учебника, и в документации была идея многоадресной рассылки.

Убедитесь, что вы знаете, что по умолчанию несколько подписок инициируют несколько выполнений в Observable. Несколько подписок на один HTTP-вызов Observable вызовет несколько идентичных HTTP-вызовов, если только вы не .share() (включите многоадресную рассылку).

Обещание заставляет вас иметь дело с одной вещью за раз, разворачивать ее данные, обрабатывать исключения, имеет языковую поддержку для таких классных вещей, как async/await, а в остальном довольно скромно.

Обсерватория имеет много наворотов, но вам нужно понимать силу, с которой вы работаете, иначе ее можно использовать не по назначению.

Ответ 23

Promise:

Async Event Handler - объект Promise представляет возможное завершение (или сбой) асинхронной операции и ее результирующее значение.

Синтаксис: новый Promise (исполнитель);

Например:

var promise_eg = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

promise_eg.then(function(value) {
  console.log(value);
  // expected output: "foo"
});

console.log(promise_eg);

enter image description here

О Promise: у него есть один конвейер, поэтому он будет возвращать значения только один раз при его вызове. его односторонний обработчик, поэтому однажды вызванный вы не сможете отменить. полезный синтаксис вы можете поиграть, когда(), а затем()

Наблюдаемые:

Observables - это ленивые коллекции нескольких значений с течением времени. это действительно отличный подход для асинхронных операций. это можно сделать с помощью rxjs, который поддерживает кроссплатформенность, может использовать angular/реагировать и т.д.

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

Синтаксис: import * as Rx from "@reactivex/rxjs"; инициировать:

Rx.Observable.fromEvent(button, "click"),
Rx.Subject()

так далее

подписаться: RxLogger.getInstance();

Например:

import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';

range(1, 200).pipe(
  filter(x => x % 2 === 1),
  map(x => x + x)
).subscribe(x => console.log(x));

Так как он поддерживает многопоточный конвейер, вы можете подписать результат в другом месте, enter image description here у него больше возможностей, чем обещаний.

Использование: у него больше возможностей, таких как map, filter, pipe, map, concatMap etc

Ответ 24

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

enter image description here

Ответ 25

Observables и Promises помогают нам работать с асинхронными функциями в JavaScript/typcript. Во многих случаях они очень похожи, однако между ними все еще есть некоторые различия.

enter image description here

Ответ 26

На эту тему уже есть много ответов, поэтому я бы не стал добавлять лишний.

Но кому-то, кто только начал изучать Observable/Angular и задается вопросом, какой из них сравнить с Promise, я бы порекомендовал вам сохранить все Observable и преобразовать все существующие Обещания в вашем проекте в Observable.

Просто потому, что сама структура Angular и ее сообщество используют Observable. Так что было бы полезно, когда вы интегрируете сервисы инфраструктуры или сторонние модули и объединяете все воедино.


Хотя я ценю все отрицательные отзывы, но все же настаиваю на своем мнении выше, если кто-то не оставит надлежащий комментарий, чтобы перечислить несколько сценариев, которые все еще могут быть полезны в вашем Angular проекте для использования Promises over Observables.

Конечно, ни одно мнение не является на 100% правильным во всех случаях, но, по крайней мере, я думаю, что 98% времени для обычных коммерческих проектов, реализованных в Angular Framework, Observable - верный путь.

Даже если вам не понравится в начале вашего простого хобби-проекта, вы скоро поймете, что почти все компоненты, с которыми вы взаимодействуете в Angular, и большинство дружественных сторонних фреймворков Angular используют Observables, а затем вы в конечном итоге постоянно преобразовывал ваше Обещание в Observable, чтобы общаться с ними.

Эти компоненты включают, но не ограничиваются: HttpClient, построитель форм, модули/диалоги угловых материалов, хранилище/эффекты Ngrx и ngx-bootstrap.

Фактически, единственное обещание от экосистемы Angular, с которым я имел дело в последние 2 года, - это APP_INITIALIZER.

Ответ 27

Объясните со ссылкой на Angular Http вызовы для удаленного Api: Promises используется для поддержания состояния асинхронных вызовов. один данные получены из удаленного Api и показать в поле зрения

и в Observable приходят из наблюдаемой модели и вводятся Rxjs, когда она дает вам возможность многократно обновлять данные в потоке как наблюдаемые данные.