В чем разница между Promise и Observable в Angular?

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

Ответы (31)

Обещание

A Promise обрабатывает одиночное событие при завершении или сбое асинхронной операции.

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

Наблюдаемый

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

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

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

В то время как Promise запускается немедленно, Observable запускается только в том случае, если вы подписываетесь на него. Вот почему Observables называют ленивыми.

Observable предоставляет операторы например map, forEach, reduce, ... аналогично массиву

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

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

Promises

  1. Definition: Helps you run functions asynchronously, and use their return values (or exceptions), but only once when executed.
  2. Not lazy
  3. Not cancellable (there are Promise libraries out there that support cancellation, but ES6 Promise doesn't so far). The two possible decisions are
    • Reject
    • Resolve
  4. Cannot be retried (Promises should have access to the original function that returned the promise to have a retry capability, which is a bad practice)

Observables

  1. Definition: Helps you run functions asynchronously, and use their return values in a continuous sequence (multiple times) when executed.
  2. By default, it is lazy as it emits values when time progresses.
  3. Has a lot of operators which simplifies the coding effort.
  4. One operator retry can be used to retry whenever needed, also if we need to retry the observable based on some conditions retryWhen can be used.

Note: A list of operators along with their interactive diagrams is available here at **RxMarbles.com**

• 100001 100002 *

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

• 100001 100002 *
 fetchValueList (listCode): Promise  {
      вернуть this.dataSvc.getValueList (listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
          .map (ответ => response.json ())
          .обещать();
  }

  initializeDropDowns () {
      this.fetchValueList ('Первый Val-List')
          .then (data => {
              this.firstValList = данные;
              return this.fetchValueList ('Второй-Val-List')
          }). then (data => {
              this.secondValList = данные;
              вернуть this.fetchValueList ('Третий-Val-List')
          }). then (data => {
              this.thirdValList = данные;
          })}

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

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

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

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

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

Обещание:

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

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

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

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

Promises and Observables image

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

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

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

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

Я суммировал различия ниже,

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

  1. Observable - это просто функция, которая принимает наблюдателя и возвращает функцию Observer: объект со следующим, ошибка.
  2. Observer позволяет подписаться / отписаться на свой поток данных, отправить следующее значение для наблюдателя, уведомить наблюдателя о ошибках и сообщить наблюдателю о завершении потока
  3. Observer предоставляет функцию для обработки следующего значения, ошибок и конец потока (UI события, HTTP-ответы, данные с веб-сокетами).
  4. Работает с несколькими значениями с течением времени
  5. Это возможность отмены / повторения и поддерживает такие операторы, как map, filter, reduceи т. Д.
  6. Создание Observable может быть -Observable.create () - возвращает Observable, который может вызывать методы на -Observer Observable.from () - преобразует массив или итерацию в -Observable Observable.fromEvent () - конвертирует событие в Observable -Observable.fromPromise () - конвертирует Promise в Observable -Observable.range () - возвращает последовательность целых чисел в указанном диапазоне

Обещание:

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

  2. Обещания становятся разрешаются значением;

  3. Обещания отклоняются исключениями;

  4. Не отменяется и возвращает одно значение

  5. Обещание предоставляет функцию (затем)

    - затем возвращает новое обещание;

    -разрешает вложение, которое будет выполнено на основе состояние;

    -обработчики являются гарантированно для исполнения в прикрепленном заказе;

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

Observable - предоставляет несколько будущих значений. Ленивый. Отменяемый. Он предоставляет другие методы, такие как map, filterи reduce.

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

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

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


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

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

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

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

Обзор:

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

Вы всегда можете использовать наблюдаемый объект для работы с асинхронным поведением, поскольку наблюдаемый объект имеет все функции, которые предлагает обещание (+ дополнительные). Однако иногда эта дополнительная функциональность, которую предлагают 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 с сервером, он с течением времени выталкивает данные.

В самом Observable указывается, когда произошло следующее событие, когда возникает ошибка или когда Observable завершено. Затем мы можем подписаться на этот наблюдаемый объект, который активирует его, и в этой подписке мы можем передать 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 подписан на него, он будет вызывать соответствующие обратные вызовы, переданные в подписку.

Хотя ответ Гюнтера Цохбауэра в целом хорош, я не думаю, что он подчеркивает, что при работе с угловыми компонентами вы почти всегда хотите использовать 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();
  });
}

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

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

Это немного надуманный пример, но выполнение кода для разрушенного компонента, вероятно, приведет к ошибкам.

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

enter image description here

Both Promises and Observables help us dealing with asynchronous operations. They can call certain callbacks when these asynchronous operations are done.

Angular uses Observables which is from RxJS instead of promises for dealing with HTTP

Below are some important differences in promises & Observables.

difference between Promises and Observables

Сначала обещание и наблюдаемое сходство

  1. Оба используются для обработки асинхронного кода.

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

    const promise = new Promise (resolve => {
      setTimeout (() => {
        resolve («Привет из обещания!»);
      }, 2000);
    });
    
    обещание.then (значение => console.log (значение));
    
  3. Теперь наблюдаемый пример. Здесь мы также передаем функцию наблюдаемому - наблюдателю для обработки асинхронной задачи. В отличие от resolve в обещании, он имеет следующий метод и подписывается вместо then.

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

    const observable = new Observable (Observable => {
      setTimeout (() => {
        наблюдатель.next ('Привет от наблюдаемого!');
      }, 2000);
    });
    
    observable.subscribe (значение => console.log (значение));
    

Разница между обещаниями и наблюдаемыми

Обещание

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

Наблюдаемый

  1. возможность передавать несколько асинхронных значений.

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

  3. Observables полезны для наблюдения за изменениями ввода, повторяющимся интервалом, широковещательными значениями для всех дочерних компонентов, push-уведомлениями веб-сокетов и т. Д.

  4. Можно отменить подписку в любое время.

  5. Еще одна хорошая часть обещания - это поддержка операторов rxjs. У вас есть много операторов каналов, в основном map, filter, switchMap, combLatest и т. Д. Для преобразования наблюдаемых данных перед подпиской.

    Enter image description here

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

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

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

Обещание: обещание выдает одно значение

Например:

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

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

Наблюдаемый: Выдает несколько значений за период времени

Например:

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

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

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

Обещание:

  • Обещание не лениво
  • Обещание не может быть отменено

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

  • Observable - ленивый. «Наблюдаемое» работает медленно. Это не называется до тех пор, пока мы подписаны на него.
  • Observable можно отменить с помощью метода unsubscribe ()
  • Дополнение Observable предоставляет множество мощных операторов, таких как map, foreach, filter, reduce, retry, retryWhen и т. д.

Угловые обещания и наблюдаемые

Promise emits a single value while Observable emits multiple values. So, while handling a HTTP request, Promise can manage a single response for the same request, but what if there are multiple responses to the same request, then we have to use Observable. Yes, Observable can handle multiple responses for the same request.

Promise

const promise = new Promise((data) =>
{ data(1);
  data(2);
  data(3); })
.then(element => console.log(‘Promise ‘ + element));

Output

Promise 1

Observable

const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));

Output

Observable 1
Observable 2
Observable 3
  1. Промисы ориентированы только на отдельные значения или разрешаются. Наблюдаемые - это поток данных.

  2. Наблюдаемые можно отменить, но обещания отменить нельзя.

Наименее известный, по крайней мере, для меня:

  1. Обещания всегда асинхронны, но наблюдаемые могут быть как синхронными, так и асинхронными.

Если вы хотите прочитать об этом подробно, я написал сообщение в блоге, следующее за этим ответом - 4 различия между Observables и Promises в JavaScript

Еще одно отличие: Глобальный vs. импортированный

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

const myPromise = new Promise ((разрешить, отклонить) => {
  setTimeout (() => {
    resolve ('готов без установки');
  }, 300);
});

мое обещание
.then (значение => {console.log (значение)})
.catch (err => {console.log (err)});

Наблюдаемый, Реактивные расширения для JavaScript Установка RxJS & импорт перед использованием

import { Observable } from 'rxjs';
  1. Promise нетерпеливый, тогда как Observable ленивый.
  2. Promise всегда асинхронный, а Observable может быть либо синхронный или асинхронный.
  3. Promise может предоставить единственное значение, тогда как Observable - это
    поток значений (от 0 до нескольких значений).
  4. Вы можете применить операторы RxJS к Observable, чтобы получить новый адаптированный поток.

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

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

Дополнительная литература: Как я могу `await` на Rx Observable?

Допустим, вы хотите пойти на пляж. Вы должны принимать решение, основываясь на погоде. У вас есть три способа:

  1. Вы смотрите на улицу и видите капли дождя, значит, вы передумали. Это синхронизированная операция. Вы прекратили то, что делали, пошли посмотреть снаружи, получили результат, а затем вернулись к тому, что делали.

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

  3. На этот раз вы включаете радио и слушаете погодный канал, который транслирует погодные условия 24/7. В этом сценарии вместо получения одного единственного ответа ответ продолжается. Этот ответ похож на подписку на наблюдаемую. наблюдаемая - это «погода», а подписка - «радиосигналы, которые держат вас в курсе». Пока ваше радио включено, вы получаете все доступные обновления. Вы не пропустите никакой информации, пока не выключите радио. При выключении радио значит "ты отписался".

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

Enter image description here

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

Обещания автоматически выполняются в приложении, в то время как наблюдаемые объекты ленивы. Мы должны подписаться на наблюдаемые объекты, чтобы возвращать данные.

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

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

myPromise.then((resolvedValue) => {
    console.log(resolvedValue);
}, (error) => {
    console.log(error);
});

Observable: - это объект, предоставляемый библиотекой Rxjs, который помогает нам работать с реактивным программированием в приложениях JavaScript, который обеспечивает цепочку и подписку для обработки сложных приложений, имеющих преимущество отменяемых и предоставляющих множество значений. в то же время. Кроме того, мы можем извлечь выгоду из применения цепочки других операторов, таких как retry (), map (), filter (), switchMap ()и т. д., что помогает справляться со сложными вариантами использования и тяжелыми пользовательскими интерфейсами.

Пример мгновенного поиска:

search(terms: Observable) {
    return terms.pipe(
      debounceTime(400),
      distinctUntilChanged(),
      switchMap((term) => this.searchEntries(term))
    );
  }

Пример нескольких параллельных вызовов APIS:

let character = this.http.get('https://jsonplaceholder.typicode.com/todos');
    let characterHomeworld = this.http.get(
      'https://jsonplaceholder.typicode.com/posts'
    );

    forkJoin([character, characterHomeworld]).subscribe((results) => {
      console.log('result °', results[0]);
      console.log('result 1', results[1]);
    });

Я вижу много людей, использующих аргумент, что Observable «отменяемые», но сделать Promise «отменяемым» довольно тривиально.

function cancellablePromise (body) {
  позвольте разрешить, отвергнуть;
  const promise = новое обещание ((res, rej) => {
    resolve = res; отклонить = rej;
    тело (разрешить, отклонить)
  })
  обещание.resolve = разрешить;
  обещание.reject = отклонить;
  обещание возврата
}

// Пример 1: преждевременно отклонить обещание
const p1 = cancellablePromise ((разрешить, отклонить) => {
  setTimeout (() => разрешить ('10 ', 100))
})

p1.then (значение => предупреждение (значение)). catch (err => console.error (err))
p1.reject (new Error ('denied')) // ожидаем ошибки в консоли

// Пример: преждевременно выполнить обещание
const p2 = cancellablePromise ((разрешить, отклонить) => {
  setTimeout (() => решить ('blop'), 100)
})

p2.then (значение => предупреждение (значение)). catch (err => console.error (err))
p2.resolve (200) // ожидаем алерт с 200

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

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

• 100001

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

Обещание:

  • Укажите единую будущую стоимость;
  • Не ленивый;
  • Не подлежит отмене;

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

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

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

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

Обещание

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

Наблюдаемый

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

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

Promises и Observables обрабатывают только асинхронный вызов.

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

Наблюдаемый

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

Обещание

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

  2. Вызывает сервисы без .then и .catch

  3. Нельзя отменить

  4. Не предоставляет операторов

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

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


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

Обещания:

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

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

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

Both Promises and Observables provide us with abstractions that help us deal with the asynchronous nature of our applications. The difference between them was pointed out clearly by Günter and @Relu.

Since a code snippet is worth a thousand words, let’s go through the below example to understand them easier.

Thanks @Christoph Burgdorf for the awesome article


Angular uses Rx.js Observables instead of promises for dealing with HTTP.

Suppose that you are building a search function that should instantly show you results as you type. It sounds familiar, but there are a lot of challenges that come with that task.

  • We don't want to hit the server endpoint every time user presses a key. It should flood them with a storm of HTTP requests. Basically, we only want to hit it once the user has stopped typing instead of with every keystroke.
  • Don’t hit the search endpoint with the same query parameters for subsequent requests.
  • Deal with out-of-order responses. When we have multiple requests in-flight at the same time we must account for cases where they come back in unexpected order. Imagine we first type computer, stop, a request goes out, we type car, stop, a request goes out. Now we have two requests in-flight. Unfortunately, the request that carries the results for computer comes back after the request that carries the results for car.

The demo will simply consist of two files: app.ts and wikipedia-service.ts. In a real world scenario, we would most likely split things further up, though.


Below is a Promise-based implementation that doesn’t handle any of the described edge cases.

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]);
  }
}

We are injecting the Jsonp service to make a GET request against the Wikipedia API with a given search term. Notice that we call toPromise in order to get from an Observable to a Promise. Eventually end up with a Promise> as the return type of our search method.

app.ts

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

@Component({
  selector: 'my-app',
  template: `
    

Wikipedia Search

  • {{item}}
` }) export class AppComponent { items: Array; constructor(private wikipediaService: WikipediaService) {} search(term) { this.wikipediaService.search(term) .then(items => this.items = items); } }

There is not much of a surprise here either. We inject our WikipediaService and expose its functionality via a search method to the template. The template simply binds to keyup and calls search(term.value).

We unwrap the result of the Promise that the search method of the WikipediaService returns and expose it as a simple array of strings to the template so that we can have *ngFor loop through it and build up a list for us.

See the example of Promise-based implementation on Plunker


Where Observables really shine

Let’s change our code to not hammer the endpoint with every keystroke, but instead only send a request when the user stopped typing for 400 ms

To unveil such super powers, we first need to get an Observable that carries the search term that the user types in. Instead of manually binding to the keyup event, we can take advantage of Angular’s formControl directive. To use this directive, we first need to import the ReactiveFormsModule into our application module.

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 {}

Once imported, we can use formControl from within our template and set it to the name "term".


In our component, we create an instance of FormControl from @angular/form and expose it as a field under the name term on our component.

Behind the scenes, term automatically exposes an Observable as property valueChanges that we can subscribe to. Now that we have an Observable, overcoming the user input is as easy as calling debounceTime(400) on our Observable. This will return a new Observable that will only emit a new value when there haven’t been coming new values for 400 ms.

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

It would be a waste of resources to send out another request for a search term that our application already shows the results for. All we have to do to achieve the desired behavior is to call the distinctUntilChanged operator right after we called debounceTime(400)

See the example of Observable implementation on Plunker

For dealing with out-of-order responses, please check the full article http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

As far as I am using HTTP in Angular, I agree that in the normal use cases there is not much difference when using Observable over Promise. None of the advantages are really relevant here in practice. I hope I can see some advanced use case in the future :)


Learn more

Обещание:

Обработчик асинхронных событий - объект 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

Об обещании:

У него один конвейер, поэтому он будет возвращать значения только один раз при вызове. Это односторонний обработчик, поэтому после вызова вы не сможете отменить. Полезный синтаксис, с которым вы можете поиграть, when () и then ().

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

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

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

Синтаксис: импорт * как Rx из «@ 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и т. Д. .

2022 WebDevInsider