在Angular中Promise和Observable之间有什么区别?

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


当前回答

还有一个区别:全球与进口

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

const myPromise=新Promise((解析,拒绝)=>{setTimeout(()=>{解决(“无需安装即可”);}, 300);});我的承诺.then(值=>{console.log(值)}).catch(错误=>{console.log(错误)});

JavaScript的可观察、反应式扩展需要RxJS安装和导入才能使用

import { Observable } from 'rxjs';

其他回答

概述:

Promise和Observables都帮助我们处理异步操作。当这些异步操作完成时,它们可以调用某些回调。Promise只能处理一个事件,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将从挂起状态变为resolved或reject状态。当promise状态被解析时,将调用then()方法。当promise状态被拒绝时,将调用catch()方法。

何时使用Observables:

当一段时间内存在需要处理的数据流时,使用Observables。流是一系列随时间而可用的数据元素。流的示例有:

用户事件,例如单击或键控事件。用户随时间生成事件(数据)。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被订阅时,它将调用传入订阅的相应回调。

我相信所有其他的答案都会消除你的疑虑。然而,我只是想补充一点,可观测性是基于函数式编程的,我发现它附带的函数非常有用,比如map、flatmap、reduce、zip。web实现的一致性,尤其是当它依赖于API请求时,是一种残酷的改进。

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

如果你想了解可观测性,我建议你写一篇三部分的文章:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

虽然它是针对RxJava的,但概念是相同的,而且解释得很好。在reactiveX文档中,您拥有每个函数的等效项。您必须查找RxJS。

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

你往外面看,看到雨点,所以你改变了主意。这是一个同步操作。你停止了你正在做的事情,去外面看看,得到了结果,然后回到你正在做什么。你请你旁边的哥哥检查一下今天的天气状况。当他在检查天气时,你仍然在做你正在做的事情。这是一个异步操作。你把一项任务交给了你的兄弟,等待承诺得到解决。在这种情况下,您将得到一个响应,在得到响应后,您将不再得到任何更新。这一次,你打开收音机,收听全天候播报天气状况的天气频道。在这种情况下,响应是持续的,而不是得到一个响应。此响应类似于订阅可观察的。可观测的是“天气”,订阅的是“让你不断更新的无线电信号”。只要你的收音机开着,你就会得到所有可用的更新。在你关掉收音机之前,你不会错过任何信息。当你关闭收音机时,意味着“你已取消订阅”。

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

我刚刚处理了一个问题,Promise是最好的解决方案,我将在这里分享给任何在有用的情况下遇到这个问题的人(这正是我之前寻找的答案):

在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再次调用,返回值在next.then块中的数据变量中,我们将其分配给this.secondValList变量。

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

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