HttpClient
返回的observable通常只发出一个值然后完成,表面上看起来很像promise。然而,这样做纯粹是为了一致性和/或者拒绝在Angular中总是使用promises这个想法并不正确。正如其他人所指出的,
async pipe支持promise,
application init也一样。那么为什么要使用observables而不是promises进行http请求?因为observables提供了另一层抽象。
在你链接的那个线程中,这个评论提出了一个关键点:
@gman确实如此。Promise只表示某些未来的值。它并不代表生成该值的操作。您无法取消值。您无法重试值。它只是一个值。它可能已经存在,也可能不存在,因为发生了异常,但仅此而已。
取消
让我们谈谈取消HTTP请求。在observable的情况下,HttpXhrBackend
只是HttpBackend
的一个实现,并且通过调用XMLHttpRequest.abort()
处理observable的取消:
return () => {
xhr.removeEventListener('error', onError);
xhr.removeEventListener('load', onLoad);
if (req.reportProgress) {
xhr.removeEventListener('progress', onDownProgress);
if (reqBody !== null && xhr.upload) {
xhr.upload.removeEventListener('progress', onUpProgress);
}
}
if (xhr.readyState !== xhr.DONE) {
xhr.abort();
}
};
请注意,当您使用此 Promise 时,您实际上并不关心它是否使用 XMLHttpRequest,它也可以使用 SomeWhackyAngularXMLHttpRequestThatIsBetter。假设我们返回一个 promise:
function myHttpGetPromise(method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
您的客户如何仅通过该Promise取消请求? 您必须执行以下两项操作之一:
- 以某种方式公开实现(在本例中为我们的
XMLHttpRequest
实例)。
- 提供您自己的抽象层,在
XMLHttpRequest
周围(类似于支持中止的httpPromise
)中添加另一层抽象来允许取消。
重用
Promise不能被重用。 假设您想使用Promise重试HTTP请求。 您会如何处理? 您需要添加另一层抽象。 在可观察对象的情况下,我们有内置的重试支持。
结论
最后值得一提的是,angular HttpClient
并不总是返回一个值。 如果将reportProgress
设置为true,则会在请求完成时发出多个HttpEvents
事件。 有关更多信息,请参见文档。 最后,您应该阅读在Angular存储库中讨论此问题的原始问题,以了解更多背景信息。
switchMap
、takeWhile
和forkJoin
就足够调用一个 API。 - Eliseo