在Angular中Promise和Observable之间有什么区别?
每一个例子都有助于理解这两种情况。在什么情况下,我们可以使用每种情况?
在Angular中Promise和Observable之间有什么区别?
每一个例子都有助于理解这两种情况。在什么情况下,我们可以使用每种情况?
当前回答
我刚刚处理了一个问题,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方法是理想的。
其他回答
以下是承诺和可观察性的一些重要区别。
许诺
仅发射单个值不可取消不可共享始终异步
可观察的
发出多个值仅在调用或有人订阅时执行可以取消可以由多个订阅者共享和订阅该共享值。所有订阅者都将在一个时间点执行。可能是异步的
为了更好地理解,请参阅https://stackblitz.com/edit/observable-vs-promises
Promise在异步活动完成或失败时发出单个事件。
Observable类似于流(在许多语言中),允许传递至少零个或多个事件,其中每个事件都需要回调。
与Promise相比,Observable通常更受欢迎,因为它提供了Promise等的亮点。使用Observable,您是否需要处理0、1或各种事件并不重要。您可以针对每种情况使用类似的API。
承诺:promise只产生一种价值
例如:
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
我们可以想象一个可观察的流,它在一段时间内发出多个值,对发出的每个项调用相同的回调函数。无论该数据是作为单个值还是作为多个值在某段时间内传输。
承诺:
承诺不是懒惰承诺不能取消
可观察:
可观察就是懒惰。“可观察”是缓慢的。直到我们订阅了它。可以使用unsubscribe()方法取消Observable另外,Observable提供了许多强大的运算符,foreach、filter、reduce、retry、retryWhen等。
角度承诺与可观测
Promise在异步操作完成或失败时处理单个事件。
承诺在应用程序中自动执行,而可观测则是惰性的。所以我们必须订阅可观测值以返回数据。
我们不能取消订阅承诺。与可取消订阅的Observables相比,它们每次都会执行。
我相信所有其他的答案都会消除你的疑虑。然而,我只是想补充一点,可观测性是基于函数式编程的,我发现它附带的函数非常有用,比如map、flatmap、reduce、zip。web实现的一致性,尤其是当它依赖于API请求时,是一种残酷的改进。
我强烈推荐这个文档,因为它是reactiveX的官方文档,我发现它是最清晰的。
如果你想了解可观测性,我建议你写一篇三部分的文章:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
虽然它是针对RxJava的,但概念是相同的,而且解释得很好。在reactiveX文档中,您拥有每个函数的等效项。您必须查找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被订阅时,它将调用传入订阅的相应回调。