在Angular中Promise和Observable之间有什么区别?
每一个例子都有助于理解这两种情况。在什么情况下,我们可以使用每种情况?
在Angular中Promise和Observable之间有什么区别?
每一个例子都有助于理解这两种情况。在什么情况下,我们可以使用每种情况?
当前回答
Promise和Observables将帮助我们使用JavaScript中的异步功能。它们在许多情况下非常相似,但是,两者之间仍然存在一些差异,承诺是以HTTP调用等异步方式解析的值。另一方面,可观测性处理一系列异步事件。它们之间的主要区别如下:
承诺:
有一条管道通常仅用于异步数据返回不容易取消
可观察:
可取消本质上是可重新测试的,例如重试和retryWhen多个管道中的流数据具有类似数组的操作,如map、filter等可以从其他来源(如事件)创建它们是功能,稍后可以订阅
此外,我为您创建了下图,以直观地显示差异:
其他回答
许诺
Promise在异步操作完成或失败时处理单个事件。
注意:有Promise库支持取消,但ES6 Promise目前还没有。
可观察的
Observable就像一个流(在许多语言中),允许传递零个或多个事件,并为每个事件调用回调。
与Promise相比,Observable通常更受欢迎,因为它提供了Promise等特性。使用Observable,无论您想处理0、1或多个事件。您可以在每种情况下使用相同的API。
Observable也比Promise具有可取消的优势。如果不再需要对服务器的HTTP请求或其他昂贵的异步操作的结果,则Observable的Subscription允许取消订阅,而Promise最终将调用成功或失败回调,即使您不再需要通知或它提供的结果。
当Promise立即启动时,Observable只有在您订阅它时才会启动。这就是为什么Observable被称为lazy。
Observable提供了map、forEach、reduce等运算符。。。类似于阵列
还有一些强大的运算符,如retry()或replay()。。。这通常很方便。rxjs附带的操作员列表
惰性执行允许在通过订阅执行可观察到的操作之前建立一个运算符链,以进行更具声明性的编程。
我相信所有其他的答案都会消除你的疑虑。然而,我只是想补充一点,可观测性是基于函数式编程的,我发现它附带的函数非常有用,比如map、flatmap、reduce、zip。web实现的一致性,尤其是当它依赖于API请求时,是一种残酷的改进。
我强烈推荐这个文档,因为它是reactiveX的官方文档,我发现它是最清晰的。
如果你想了解可观测性,我建议你写一篇三部分的文章:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
虽然它是针对RxJava的,但概念是相同的,而且解释得很好。在reactiveX文档中,您拥有每个函数的等效项。您必须查找RxJS。
承诺是渴望的,而可观察者是懒惰的。Promise总是异步的,而Observable可以是同步或异步。Promise可以提供单个值,而Observable是值流(从0到多个值)。您可以将RxJS运算符应用于Observable,以获得新的定制流动
承诺:
异步事件处理程序-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等。
虽然Günter Zöchbauer的回答总体上是好的,但我不认为它强调了在处理角度分量时,您几乎总是希望使用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();
});
}
如果您的组件在promise解析之前被销毁,那么在promise被解析时,您将尝试使用已销毁的视图错误。
或者,如果您在takeUntil模式中使用可观测值,那么一旦您的组件被破坏,订阅就会被取消。
这是一个有点做作的例子,但为被破坏的组件执行代码可能会导致错误。