1709

PromiseAngular和Angular有什么区别Observable

每个例子都有助于理解这两种情况。我们可以在什么情况下使用每种情况?

4

31 回答 31

1891

承诺

A在异步操作完成或失败时Promise处理单个事件。

注意:那里Promise有支持取消的库,但 ES6Promise到目前为止还没有。

可观察的

AnObservable就像 a Stream(在许多语言中)并允许传递零个或多个事件,其中为每个事件调用回调。

通常Observable是首选,Promise因为它提供了Promise更多的功能。如果您想处理 0、1 或多个事件,Observable这并不重要。您可以在每种情况下使用相同的 API。

Observable还有一个优势Promise就是可以取消。如果不再需要对服务器的 HTTP 请求或其他一些昂贵的异步操作的结果,则Subscription允许Observable取消订阅,而Promise即使您不需要通知,最终也会调用成功或失败回调或它提供的结果。

虽然 aPromise立即启动,但Observable仅当您订阅它时才会启动。这就是为什么 Observable 被称为惰性的原因。

Observable 提供类似于数组的运算符,如map, forEach, , ...reduce

还有一些功能强大的运算符,例如retry(), or replay(), ... 通常非常方便。 rxjs 附带的运算符列表

延迟执行允许在通过订阅执行 observable 之前建立一系列运算符,以进行更具声明性的编程。

于 2016-05-21T17:19:35.403 回答
396

两者都PromisesObservables我们提供了抽象,帮助我们处理应用程序的异步特性。Günter和@Relu清楚地指出了它们之间的区别。

由于代码片段值一千字,让我们通过下面的示例更容易理解它们。

感谢@Christoph Burgdorf的精彩文章


Angular 使用 Rx.js Observables 而不是 Promise 来处理 HTTP。

假设您正在构建一个搜索功能,该功能应在您键入时立即显示结果。这听起来很熟悉,但是这项任务会带来很多挑战。

  • 我们不想在每次用户按键时都点击服务器端点。它应该用大量的HTTP请求来淹没它们。基本上,我们只想在用户停止打字而不是每次击键时点击它。
  • 不要为后续请求使用相同的查询参数命中搜索端点。
  • 处理乱序响应。当我们同时处理多个请求时,我们必须考虑它们以意外顺序返回的情况。想象一下,我们首先输入computer , stop ,发出一个请求,我们输入car , stop ,发出一个请求。现在我们有两个正在处理的请求。不幸的是,携带计算机结果的请求在携带汽车结果的请求之后返回。

该演示将仅包含两个文件:app.tswikipedia-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服务以使用给定的搜索词对Wikipedia API发出GET请求。请注意,我们调用是为了从 a到 a 。最终以 a作为我们搜索方法的返回类型。toPromiseObservable<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 的搜索方法返回的Promise的结果,并将其作为简单的字符串数组公开给模板,以便我们可以*ngFor循环遍历它并为我们构建一个列表。

参见Plunker上基于 Promise 的实现示例


Observables真正闪耀的地方

让我们更改我们的代码,不要在每次击键时敲击端点,而是仅在用户停止输入400 毫秒时发送请求

为了展示这些超能力,我们首先需要获得一个Observable<string>带有用户输入的搜索词的参数。我们可以利用 Angular 的formControl指令,而不是手动绑定到 keyup 事件。要使用此指令,我们首先需要将 导入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"/>

在我们的组件中,我们创建了一个FormControlfrom的实例,@angular/form并将其公开为我们组件上名为 term 的字段。

在幕后,term自动公开了一个我们可以订阅的Observable<string>as 属性。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 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));
  }
}

发送另一个对我们的应用程序已经显示结果的搜索词的请求会浪费资源。为了达到预期的行为,我们所要做的就是distinctUntilChanged在我们调用之后立即调用操作员debounceTime(400)

请参阅Plunker上的Observable实现示例

对于无序响应的处理,请查看完整文章 http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

就我在 Angular 中使用 HTTP 而言,我同意在正常用例中使用 Observable over Promise 并没有太大区别。在实践中,这些优点都不是真正相关的。我希望将来能看到一些高级用例:)


学到更多

于 2016-10-19T15:17:47.783 回答
300

PromisesObservables都将帮助我们使用 JavaScript 中的异步功能。在许多情况下,它们非常相似,但是两者之间也存在一些差异,promise 是以asynchronousHTTP 调用之类的方式解析的值。另一方面,可观察对象处理一系列异步事件。它们之间的主要区别如下:

承诺:

  • 有一个管道
  • 通常只与异步数据返回一起使用
  • 不容易取消

可观察的:

  • 可以取消
  • 本质上是可重试的,例如 retry 和 retryWhen
  • 在多个管道中流式传输数据
  • 具有类似数组的操作,如 map、filter 等
  • 可以从其他来源(如事件)创建
  • 它们是函数,以后可以订阅

此外,我在下面为您创建了图形图像,以直观地显示差异:

Promise 和 Observables 图像

于 2017-05-07T06:56:17.837 回答
106

答案中缺少 Observables 的一个缺点。Promise 允许使用 ES7 的 async/await 函数。使用它们,您可以编写异步代码,就像它是一个同步函数调用一样,因此您不再需要回调。Observables 这样做的唯一可能性是将它们转换为 Promise。但是当你将它们转换为 Promises 时,你只能再有一个返回值:

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

进一步阅读:如何在 Rx Observable 上“等待”?

于 2017-06-28T20:45:08.100 回答
86

承诺

  1. 定义:帮助您异步运行函数,并使用它们的返回值(或异常),但在执行时使用一次。
  2. 不懒惰
  3. 不可取消(那里有支持取消的 Promise 库,但 ES6 Promise 到目前为止还没有)。两个可能的决定是
    • 拒绝
    • 解决
  4. 不能重试(Promises 应该可以访问返回该 Promise 的原始函数以具有重试能力,这是一种不好的做法)

可观察的

  1. 定义:帮助您异步运行函数,并在执行时以连续序列(多次)使用它们的返回值。
  2. 默认情况下,它是惰性的,因为它会随着时间的推移发出值。
  3. 有很多运算符,简化了编码工作。
  4. 一个 operator retry可用于在需要时重试,如果我们需要根据某些条件重试 observable,也可以使用retryWhen 。

注意: **RxMarbles.com上提供了运算符列表及其交互式图表**

于 2017-01-09T18:29:50.417 回答
49

Promises 和 Observables 都只处理异步调用。

以下是它们之间的区别:

可观察的

  1. 在一段时间内发出多个值
  2. 在我们订阅 Observable 之前不会被调用
  3. 可以使用 unsubscribe() 方法取消
  4. 提供 map、forEach、filter、reduce、retry 和 retryWhen 运算符

承诺

  1. 一次只发出一个值

  2. 调用不带 .then 和 .catch 的服务

  3. 无法取消

  4. 不提供任何运算符

于 2018-01-17T16:50:45.227 回答
34

我总结了以下差异,

可观察的:

  1. Observable 只是一个function接受an observer并返回一个function Observer: an object with next, error.
  2. 观察者允许subscribe/unsubscribe对其数据流,向观察者发出下一个值,notify观察者关于errors并通知观察者关于stream completion
  3. Observer 提供了一个function to handle next value、错误和流的结束(UI事件、http 响应、带有 web 套接字的数据)。
  4. multiple values随着时间的推移工作
  5. 它是cancel-able/retry-able并支持诸如map, filter, reduce等运算符。
  6. 创建 Observable 可以 - Observable.create()- 返回可以调用方法的 Observable - Observer Observable.from()- 将数组或迭代转换为 - Observable Observable.fromEvent()- 将事件转换为 Observable - Observable.fromPromise()- 将 Promise 转换为 Observable - Observable.range()- 返回指定范围内的整数序列

承诺

  1. 承诺代表将在未来完成的任务;

  2. 承诺变成了resolved by a value

  3. Promise 被异常拒绝;

  4. 不是cancellable,它会返回a single value

  5. 一个promise暴露一个函数(then)

    - 然后返回一个新的promise

    - 允许attachment基于 state;

    -handlersguaranteed在执行order attached

于 2017-10-08T03:43:43.773 回答
27

我相信所有其他答案都应该消除您的疑虑。尽管如此,我只想补充一点,observables 是基于函数式编程的,我发现它附带的函数非常有用,例如 map、flatmap、reduce、zip。Web 实现的一致性,尤其是当它依赖于 API 请求时,这是一个残酷的改进。

我强烈推荐这个文档,因为它是 reactiveX 的官方文档,我发现它是最清楚的。

如果你想进入 observables,我建议你这篇由 3 部分组成的帖子: http ://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

虽然它是为 RxJava 设计的,但概念是相同的,而且解释得很好。在 reactiveX 文档中,您有每个函数的等价物。你必须寻找 RxJS。

于 2017-05-12T13:33:21.383 回答
26

我刚刚处理了一个问题,其中 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;
          })  }

我在组件中定义了函数,然后在ngOnInit中调用了initializeDropDowns()。

fetchValueList 函数返回一个 Promise,因此第一次调用传递了第一个 listCode,当 Promise 解析时,返回值在 .then 块中的数据变量中,我们可以将它分配给 this.firstValList 变量。由于函数返回了数据,我们知道服务已经完成,可以安全地使用第二个 listCode 再次调用,返回值在下一个 .then 块的数据变量中,我们将它分配给 this.secondValList 变量。

我们可以根据需要将其链接多次以填充所有变量,并且在最后一个代码块上,我们只需省略 return 语句并且块终止。

这是一个非常具体的用例,我们有一个服务需要在组件初始化时被多次调用,并且服务必须完成其获取并返回一个值才能再次调用它,但在这种情况下, Promise / .then 方法非常理想。

于 2017-04-12T05:25:40.703 回答
26

概述:

  • Promises 和 Observables 都可以帮助我们处理异步操作。当这些异步操作完成时,它们可以调用某些回调。
  • 一个 Promise 只能处理一个事件,Observables 用于处理一段时间内的事件流
  • 承诺一旦处于未决状态就无法取消
  • Data Observables 可以使用操作符进行转换

您始终可以使用可观察对象来处理异步行为,因为可观察对象具有承诺提供的所有功能(+额外)。但是,有时不需要 Observables 提供的这种额外功能。然后导入一个库以供它使用它们将是额外的开销。

何时使用 Promise:

当您有一个要处理其结果的异步操作时,请使用 Promise。例如:

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

因此,promise 会执行一些代码,它要么解决要么拒绝。如果调用了resolve 或reject,则promise 从挂起状态变为已解决拒绝状态。当承诺状态被解决时,该then()方法被调用。当 promise 状态被拒绝时,该catch()方法被调用。

何时使用 Observables:

当需要处理一段时间内的(数据)流时,请使用 Observables 。流是随着时间的推移而变得可用的数据元素序列。流的示例是:

  1. 用户事件,例如点击或按键事件。用户随时间生成事件(数据)。
  2. Websockets,在客户端与服务器建立 WebSocket 连接后,它会随着时间的推移推送数据。

在 Observable 本身中指定下一个事件发生的时间、错误发生的时间或 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 被订阅时,它会调用传入订阅的相应回调。

于 2018-08-11T10:02:40.600 回答
24

承诺:

  • 提供单一的未来价值;
  • 不懒惰;
  • 不可取消;

可观察的:

  • 随着时间的推移发出多个值;
  • 懒惰的;
  • 可取消;
  • 支持map、filter、reduce等操作符

如果您愿意,可以在 Angular 中调用 HTTP 时使用 promises 而不是 observables。

于 2017-10-03T09:38:02.717 回答
16

假设你想去海滩。您必须根据天气做出决定。你有三种方式:

  1. 你向外看,看到雨滴,所以你改变了主意。这是一个同步操作。你停止了你正在做的事情,去外面检查,得到结果,然后又回到你正在做的事情上。

  2. 你请你旁边的兄弟检查今天的天气状况。当他检查天气时,你仍然继续做你正在做的事情。这是一个异步操作。你给你的兄弟一个任务,等待承诺得到解决。在这种情况下,您会收到一个回复​​,在您收到回复后,您将不再收到任何更新。

  3. 这一次,您打开收音机并收听 24/7 全天候广播天气状况的天气频道。在这种情况下,响应是持续进行的,而不是得到一个响应。这个响应就像一个subscription对一个observable。observable 是“天气”,subscription 是“让您保持最新状态的无线电信号”。只要您的收音机打开,您就会获得所有可用的更新。在您关闭收音机之前,您不会错过任何信息。当您关闭收音机时,这意味着“您已取消订阅”。

于 2021-09-06T06:43:36.090 回答
15

Promise - 提供单一的未来值。不懒惰。不可取消。它会拒绝或解决。

Observable - 提供多个未来值。懒惰的。可取消。它提供了其他方法,例如mapfilterreduce

于 2018-04-11T07:36:40.340 回答
15

Promise vs Observable 相似性优先

  1. 两者都用于处理异步代码。

  2. 请查找承诺示例。Promise 构造函数传递一个解析引用函数,该函数将在完成某个异步任务后以某个值调用时被调用。

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve("Hello from a Promise!");
      }, 2000);
    });
    
    promise.then(value => console.log(value));
    
  3. 现在可以观察到的例子。在这里,我们还将一个函数传递给 observable - 一个处理异步任务的观察者。与 promise 中的 resolve 不同,它具有以下方法并订阅代替 then。

  4. 所以两者都处理异步任务。现在让我们看看区别。

    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. Observable 可用于观察输入变化、重复间隔、向所有子组件广播值、Web 套接字推送通知等。

  4. 可以随时使用取消订阅方法取消。

  5. 承诺的最后一个好处是支持 rxjs 运算符。您有许多管道运算符,主要是映射、过滤、switchMap、combineLatest 等,以在订阅之前转换可观察数据。

    在此处输入图像描述

于 2019-06-23T12:08:57.180 回答
14

Promise 发出单个值,而 Observable 发出多个值。所以,在处理一个 HTTP 请求的时候,Promise 可以管理同一个请求的单个响应,但是如果同一个请求有多个响应,那我们就不得不使用 Observable 了。是的,Observable 可以处理同一个请求的多个响应。

承诺

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

输出

Promise 1

可观察的

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

输出

Observable 1
Observable 2
Observable 3
于 2019-12-30T07:32:44.163 回答
11

简短的回答:

可观察更好。它具有所有Promises功能以及额外的功能。


长答案:

承诺:

  • 一次使用“返回数据一次”
  • 没有取消
  • 一位听众
  • 不支持套接字

可观察的:

  • 数据变化时多次返回数据
  • 支持取消
  • 支持插座
  • 支持多个监听器,并在数据变化时通知它们
  • 支持map、filter和reduce
于 2018-09-30T11:57:25.000 回答
10

当异步活动完成或失败时,Promise 会发出单个事件。

Observable 类似于 Stream(在许多语言中),并且允许传递至少零个或多个事件,其中每个事件都需要回调。

通常 Observable 比 Promise 更受欢迎,因为它提供了 Promise 的亮点等等。使用 Observable,您是否需要处理 0、1 或各种事件都无关紧要。您可以对每种情况使用类似的 API。

Promise: promise 发出单个值

例如:

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

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

Observable: 在一段时间内发出多个值

例如:

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

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

我们可以将 observable 想象成一个流,它在一段时间内发出多个值,并且为每个发出的项目调用相同的回调函数,因此使用 observable 我们可以使用相同的 API 来处理异步数据。该数据是在一段时间内作为单个值还是多个值传输的。

承诺:

  • 承诺不懒惰
  • 一个 Promise 不能被取消

可观察的:

  • Observable 是惰性的。“可观察”很慢。在我们订阅它之前不会调用它。
  • 可以使用 unsubscribe() 方法取消 Observable
  • 另外 Observable 提供了许多强大的操作符,如 map、foreach、filter、reduce、retry、retryWhen 等。

Angular Promises vs Observables

于 2019-10-28T12:04:45.153 回答
8

Promises 和 Observables 都可以帮助我们处理异步操作。当这些异步操作完成时,它们可以调用某些回调。

Angular 使用来自 RxJS 的 Observables 而不是处理 HTTP 的 Promise

Below are some important differences in promises & Observables.

Promises 和 Observables 的区别

于 2019-04-29T11:05:39.760 回答
7
  1. Promise 是渴望的,而 Observable 是惰性的。
  2. Promise 始终是异步的,而 Observable 可以是同步的或异步的。
  3. Promise 可以提供单个值,而 Observable 是
    值流(从 0 到多个值)。
  4. 您可以将 RxJS 运算符应用于 Observable 以获得新的定制流。
于 2019-12-30T07:11:45.023 回答
6

以下是 Promise 和 Observable 的一些重要区别。

承诺

  • 仅发出单个值
  • 不可取消
  • 不可共享
  • 始终异步

可观察的

  • 发出多个值
  • 仅在被调用或有人订阅时执行
  • 可以取消
  • 可以由多个订阅者共享和订阅该共享值。所有订阅者都将在一个时间点执行。
  • 可能是异步的

为了更好地理解,请参阅https://stackblitz.com/edit/observable-vs-promises

于 2018-10-30T21:56:00.553 回答
6

承诺:

异步事件处理程序 - Promise 对象表示异步操作的最终完成(或失败)及其结果值。

语法: new Promise(executor);

例如:

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

在此处输入图像描述

关于承诺:

它有一个管道,因此在调用时它只会返回一次值。这是一个单向处理程序,因此一旦调用您可能无法取消。有用的语法,你可以玩,when()then()

可观察的:

Observables 是多个值随时间推移的惰性集合。这确实是异步操作的好方法。它可以使用具有跨平台支持的rxjs来完成,可以与 Angular/React 等一起使用。

它的作用类似于流线,可以是多管道。所以一旦定义好,就可以在很多地方订阅获取返回结果。

语法: 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));

由于它支持多管道,您可以在不同的位置订阅结果,

在此处输入图像描述

它比承诺有更多的可能性。

用法:

它有更多的可能性,如mapfilterpipemapconcatMap等。

于 2019-03-08T06:04:32.120 回答
5

虽然Günter Zöchbauer 的回答总体上很好,但我认为它并没有强调在处理 Angular 组件时,您几乎总是希望使用 Observable,因为它支持取消。Promise 不能被取消,即使你的组件被销毁也会解决。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();
  });
}

如果你的组件在 Promise 被解决之前被销毁,当 Promise 被解决时你会得到一个attempt to use destroyed view错误。

或者,如果您将 observables 与takeUntil模式一起使用,那么一旦您的组件被销毁,订阅就会被取消。

这是一个人为的例子,但是为被破坏的组件执行代码可能会导致错误。

于 2018-11-14T13:36:01.650 回答
5

在第一次阅读教程和文档时,我遇到的并不明显的是多播的想法。

确保您知道默认情况下,多个订阅将触发 Observable 中的多个执行。多个订阅单个 HTTP 调用 Observable 将触发多个相同的 HTTP 调用,除非您.share()(启用多播)。

Promise 迫使你一次处理一件事,解包它的数据,处理异常,对诸如 async/await 之类的很酷的东西提供语言支持,否则它是非常简单的。

Observable 有很多花里胡哨,但你需要了解你正在使用的力量,否则它可能会被滥用。

于 2019-02-13T22:45:43.777 回答
5

我看到很多人使用 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

于 2019-03-25T15:01:30.233 回答
4

Promise : 是一个 ES6 特性,它处理异步代码,它在创建时立即执行,当时只能发出一个值并且不可取消。随着现代应用程序和功能需求的复杂性,有必要实现复杂的代码,如果我们要同时执行许多 Promise,或者在执行前进行过滤或进行一些转换:

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

Observable:是 Rxjs 库提供的一个对象,它帮助我们在 JavaScript 应用程序中使用响应式编程,它提供链接和订阅来处理具有可取消优势的复杂应用程序,同时提供许多值。此外,我们可以从应用其他运算符的链接中受益,例如retry(), map(), filter(),switchMap()等,这有助于处理复杂的用例和繁重的用户界面。

即时搜索示例:

search(terms: Observable<string>) {
    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]);
    });
于 2021-07-13T20:02:20.510 回答
3
  1. Promise 仅针对单个值或解析。Observables 是数据流。

  2. Observables 可以被取消,但 Promise 不能被取消。

至少对我来说,最不为人所知的是:

  1. Promise 总是异步的,但是 observables 可以是同步的也可以是异步的。

如果您想详细了解它,我在这个答案之后写了一篇博客文章 - JavaScript 中 Observables 和 Promises 之间的 4 个区别

于 2020-01-01T17:46:40.657 回答
2

Observables 和 Promises 正在帮助我们使用 JavaScript/TypeScript 中的异步功能。它们在许多情况下非常相似,但是它们之间仍然存在一些差异。

在此处输入图像描述

于 2018-12-10T14:37:28.827 回答
2

可观察和承诺之间的基本区别是:

在此处输入图像描述

于 2019-04-15T08:55:17.343 回答
2

另一个区别:全球与进口

Promise 是一个标准的内置对象,你可以直接使用它。在此处检查浏览器支持

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ready with out any installation');
  }, 300);
});

myPromise
.then(value => { console.log(value) })
.catch(err => { console.log(err) });

JavaScript 的Observable响应式扩展需要在使用前安装和导入RxJS

import { Observable } from 'rxjs';
于 2021-07-19T15:20:54.690 回答
1

当异步操作完成或失败时,Promise 会处理单个事件。

Promise 是在应用程序中自动执行的,而 observables 是惰性的。所以我们必须订阅 observables 才能返回数据。

我们不能取消订阅承诺。与可以取消订阅的 Observable 相比,它们每次都会执行。

于 2021-09-07T07:24:17.617 回答
-1

关于这个话题已经有很多答案了,所以我不会添加多余的答案。

但是对于刚开始学习Observable / Angular并想知道将哪个与Promise进行比较的人,我建议您保留所有内容 Observable 并将项目中所有现有的 Promise 转换为 Observable。

仅仅是因为 Angular 框架本身和它的社区都在使用 Observable。因此,当您集成框架服务或第三方模块并将所有内容链接在一起时,这将是有益的。


当然,没有任何意见在所有情况下都是 100% 正确的,但至少我认为 98% 的情况下,对于在 Angular 框架中实施的常规商业项目,Observable 是正确的方法。

即使你在你的简单爱好项目的起点不喜欢它,你很快就会意识到你在 Angular 中与之交互的几乎所有组件,并且大多数对 Angular 友好的第三方框架都使用 Observables,然后你' 最终会不断地将你的 Promise 转换为 Observable 以便与他们交流。

这些组件包括但不限于:HttpClient、Form builder、Angular material modules/dialogs、Ngrx store/effects 和 ngx-bootstrap。

事实上,过去两年我处理的来自 Angular 生态系统的唯一 Promise 是APP_INITIALIZER.

于 2018-07-29T10:30:08.660 回答