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

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


当前回答

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

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

Observable:是Rxjs库提供的一个Object,它帮助我们处理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]);
    });

其他回答

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

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

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

承诺

定义:帮助您异步运行函数,并使用它们的返回值(或异常),但仅在执行时使用一次。不懒惰不可取消(有Promise库支持取消,但ES6 Promise目前还没有)。两个可能的决定是拒绝决定无法重试(promise应该可以访问返回promise的原始函数,该函数具有重试功能,这是一种错误的做法)

可观察到的

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

注:**RxMarbles.com上提供了操作员列表及其交互式图表**

承诺与可观察到的相似性

两者都用于处理异步代码。请查看承诺示例。promise构造函数传递一个解析引用函数,当它在完成某个异步任务时被某个值调用时,该函数将被调用。const promise=new promise(解析=>{setTimeout(()=>{决心(“来自承诺的问候!”);}, 2000);});promise.then(值=>console.log(值));现在是一个可观的例子。在这里,我们还将一个函数传递给observable——一个处理异步任务的观察者。与promise中的resolve不同,它具有以下方法并订阅以代替then。所以两者都处理异步任务。现在让我们看看区别。const observable=新的observable(观察者=>{setTimeout(()=>{observer。next(“来自Observable的您好!”);}, 2000);});observable.subscribe(value=>console.log(value));


承诺与显著差异

许诺

它解析或拒绝单个值,并且可以一次处理单个值的异步任务。一个promise一旦解析了它完成的异步值,就不能再使用了。它只是一次性使用,在这里它是不够的。不可取消操作员不支持rxjs。

可观察的

能够发出多个异步值。用于处理事件或值流。假设您有一个包含大量任务或值的数组,并且您希望每次将值插入其中时都能自动处理。每当您将一个值推送到这个数组中时,它的所有订阅者都会自动收到最新的值。Observable可用于观察输入更改、重复间隔、向所有子组件广播值、web套接字推送通知等。可以随时使用退订方法取消。承诺的最后一个好部分是支持rxjs运算符。在订阅之前,您有许多管道操作符(主要是map、filter、switchMap、combineLatest等)来转换可观察数据。

承诺:

异步事件处理程序-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);

关于Promise:

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

观察结果:

可观测值是一段时间内多个值的惰性集合。这是一种非常好的异步操作方法。它可以用具有跨平台支持的rxjs实现,也可以与Angular/React等一起使用。

它的作用类似于流衬垫,可以是多管道。因此,一旦定义,您可以在许多地方订阅以获得返回结果。

语法:从“@reactivex/rxjs”导入*作为Rx;初始化:

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

etc.

订阅: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));

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

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

用法:

它有更多的可能性,如贴图、过滤器、管道、贴图、concatMap等。

简短回答:

可观察性更好。它具有所有Promise功能和额外功能。


长答案:

承诺:

一次性使用“返回数据一次”不取消一位听众无插座支持

观察结果:

数据更改时多次返回数据支持取消支撑插座支持许多侦听器,并在数据更改时通知它们支持映射、过滤和减少