JavaScript 中的 observables 和 promises 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36064303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the differences between observables and promises in JavaScript?
提问by chrisjlee
So i've read that observables are looking to overtake promises in terms of usage in some of upcoming JavaScript MVC's:
所以我读到 observables 正在寻求在一些即将到来的 JavaScript MVC 的使用方面超越承诺:
What is the difference between observables and promises?
observables 和 promises 有什么区别?
Updated: Apologies! removed my falsy statement.
更新:抱歉!删除了我的虚假陈述。
采纳答案by Felix Kling
What is the difference between observables and promises?
observables 和 promises 有什么区别?
Simply put: A promise resolves to a singlevalue asynchronously, an observable resolves to (or emits) multiplevalues asynchronously (over time).
简单地说:promise异步解析为单个值,observable 异步解析(或发出)多个值(随着时间的推移)。
Concrete examples:
具体例子:
- Promise: Response from an Ajax call
- Observable: Click events
- 承诺:来自 Ajax 调用的响应
- Observable:点击事件
More information can be found here: http://reactivex.io/intro.html
更多信息可以在这里找到:http: //reactivex.io/intro.html
i've read that observables are looking to overtake promises
我读过 observables 正在寻求超越承诺
Unlikely. Observables might be the better solution to certain problems, but that doesn't make promises obsolete (if that's what you mean).
不太可能。Observables 可能是某些问题的更好解决方案,但这并不会使承诺过时(如果这就是你的意思)。
回答by Moeri
Promises are a representation of 1 future value. Observables are a representation for a possibly infinite amount of values.
承诺是 1 个未来值的表示。Observable 是可能无限数量的值的表示。
Promises will trigger the fetching of that value immediately upon creation. Observables will only start producing values when you subscribe to them. (Unless it's a hot observable, but that's outside the scope of this question)
Promise 将在创建后立即触发对该值的获取。Observables 只会在您订阅它们时才开始产生值。(除非它是一个热门的 observable,但这超出了这个问题的范围)
Promises are designed to represent AJAX calls. Observables are designed to represent anything: events, data from databases, data from ajax calls, (possibly infinite) sequences, etc.
Promise 旨在表示 AJAX 调用。Observables 旨在表示任何事物:事件、来自数据库的数据、来自 ajax 调用的数据、(可能是无限的)序列等。
回答by domino
Promises offer a very simplistic call back mechanism, where as Rx offers a powerful abstraction over asynchronous programming. An Observable represents a stream of data, which we can then apply operators to in order to define how the incoming data should be treated.
Promises 提供了一种非常简单的回调机制,而 Rx 提供了对异步编程的强大抽象。一个 Observable 代表一个数据流,然后我们可以对其应用运算符来定义应该如何处理传入的数据。
If all you need to do is make an HTTP request and then update a UI component, then using a Promise might suffice.
如果您需要做的只是发出 HTTP 请求,然后更新 UI 组件,那么使用 Promise 可能就足够了。
However, most apps tend to have more complicated needs than that (even if it's not obvious at the first). Taking our HTTP request for example, let's see how modelling this as an Observable and using some of the Rx operators can help us:
然而,大多数应用程序往往有比这更复杂的需求(即使一开始并不明显)。以我们的 HTTP 请求为例,让我们看看将其建模为 Observable 并使用一些 Rx 操作符如何帮助我们:
-If the HTTP request is triggered by a user action, we might want to be wary of firing off multiple HTTP requests (imagine a user typing into a search box). We don't want to fire a request for every keystroke, so we might want to Throttleour search, so that we only fire a request if the user stops typing for 300ms. Furthermore, if user types a word, waits 300ms, and adds another character, we'll fire off a subsequent HTTP request. With Promises, we'd probably encounter a race condition as we can't control the order in which we'll receive the responses and we can't cancel old requests. Rx solves this by allowing us to Switchbetween streams, which calls Disposeon the old request subscriptions we no longer care about. We might also filter out any invalid search inputs, for instance Wherethe search term is less than 3 characters in length.
- 如果 HTTP 请求是由用户操作触发的,我们可能要警惕触发多个 HTTP 请求(假设用户在搜索框中键入内容)。我们不想火每次击键的要求,所以我们可能要节流我们的搜索,如果用户300毫秒停止打字,使我们只火的请求。此外,如果用户输入一个单词,等待 300 毫秒,然后添加另一个字符,我们将触发后续的 HTTP 请求。使用 Promises,我们可能会遇到竞争条件,因为我们无法控制接收响应的顺序,也无法取消旧请求。Rx 通过允许我们在流之间切换来解决这个问题,这调用了Dispose关于我们不再关心的旧请求订阅。我们还可以过滤掉任何无效的搜索输入,例如当搜索词的长度小于3个字符。
-Support for dealing with Timeouts/Error handling. Let's say our HTTP request fails, Rx allows us to easily Retrymaking the request.
- 支持处理超时/错误处理。假设我们的 HTTP 请求失败,Rx 允许我们轻松地重试发出请求。
-Let's say several parts of our application need to make the same HTTP call, we probably don't want to actually make the call more than once. We can expose our observable to multiple consumers and use Replayto ensure the call is made once and the result is cached for subsequent subscribers. We can even supply a TimeSpan to Replay, giving us expiring cache behaviour.
- 假设我们的应用程序的几个部分需要进行相同的 HTTP 调用,我们可能不希望实际进行多次调用。我们可以将我们的 observable 暴露给多个消费者,并使用Replay来确保调用一次并将结果缓存给后续订阅者。我们甚至可以为 Replay 提供一个 TimeSpan,从而使我们的缓存行为过期。
-Powerful abstraction over threading through the use of Schedulers, which allows us to control concurrency. Even better, we can use Test Schedulers in our Unit Tests to control time, allowing us to simulate Timeouts, race conditions etc.
- 通过使用调度程序对线程进行强大的抽象,这使我们能够控制并发性。更好的是,我们可以在单元测试中使用测试调度程序来控制时间,允许我们模拟超时、竞争条件等。
These are some quick examples to demonstrate what is possible. There are many more operators within the Rx framework to cater for all types of scenarios and the composability of Rx means you can easily combine operators to define the behaviour you need. It's also easy to create your own reusable operators (e.g. RetryAfterDelay).
这些是一些简单的例子来演示什么是可能的。Rx 框架中有更多的运算符来满足所有类型的场景,而 Rx 的可组合性意味着您可以轻松地组合运算符来定义您需要的行为。创建您自己的可重用运算符(例如 RetryAfterDelay)也很容易。
In summary, Rx can do everything than Promises can do, and far far more. I suspect in the next couple of years there'll be a continued shift towards Rx instead of Promises.
总而言之,Rx 可以做的所有事情都比 Promises 做的多,而且远不止这些。我怀疑在接下来的几年里,将会继续转向 Rx 而不是 Promises。
For further reading, I'd recommend taking a look at the section on Observables in the Angular 2 guide.
如需进一步阅读,我建议您查看Angular 2 指南中关于 Observables 的部分。
回答by Parid0kht
as said in Angular 2 guid
Converting to a Promise is often a good choice when you want to fetch a single chunk of data. so When you receive the data, you're done.
当您想要获取单个数据块时,转换为 Promise 通常是一个不错的选择。所以当你收到数据时,你就完成了。
But in some cases requests aren't always done only once. You may start one request, cancel it, and make a different request before the server has responded to the first request.
但在某些情况下,请求并不总是只执行一次。您可以启动一个请求,取消它,然后在服务器响应第一个请求之前发出不同的请求。
for example in a search component As the user types a name into a search box, you'll make repeated HTTP requests by that search query.
例如在搜索组件中 当用户在搜索框中键入名称时,您将通过该搜索查询发出重复的 HTTP 请求。
A request-cancel-new-request sequence is difficult to implement with Promises, but easy with Observables.
request-cancel-new-request 序列很难用 Promises 实现,但用 Observables 很容易。
so if your component gets data with only one request it's a good choice to use Promise
but if it has a chain of request-cancel-new request you should use observable
因此,如果您的组件仅通过一个请求获取数据,那么使用它是一个不错的选择,Promise
但如果它有一系列 request-cancel-new 请求,您应该使用observable
回答by asad mohd
Observables are often compared to promises. Here are some key differences:
Observable 经常被比作承诺。以下是一些主要区别:
Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.
Observable 是声明性的;直到订阅才开始计算。Promise 在创建时立即执行。这使得 observables 可用于定义可在您需要结果时运行的配方。
Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.
Observables 提供了许多值。承诺提供了一个。这使得 observable 可用于随时间获取多个值。
Observables differentiate between chaining and subscription. Promises only have .then() clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.
Observable 区分链接和订阅。Promise 只有 .then() 子句。这使得 observable 可用于创建复杂的转换配方以供系统的其他部分使用,而不会导致工作被执行。
Observables subscribe() is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.
Observables subscribe() 负责处理错误。Promise 将错误推送到子 Promise。这使得 observables 可用于集中和可预测的错误处理。
Best explanation by angular on official website :
官方网站 angular 的最佳解释:
回答by Masoud Bimar
Observables VS. Promises (by Jeremy Vilken)
可观察值 VS。承诺(杰里米·维尔肯)
In addition to new syntax, observablesare a newer pattern for JavaScript applications to manage asynchronous activities. They're also a draft for a feature to be natively implemented in the JavaScript language so it has weight behind the pattern. RxJS is the library we'll use to help us implement observables in our applications.
除了新语法之外,可观察对象是 JavaScript 应用程序管理异步活动的新模式。它们也是在 JavaScript 语言中本地实现的功能的草案,因此它在模式背后具有重要意义。RxJS 是我们将用来帮助我们在应用程序中实现可观察对象的库。
Promisesare another construct to help deal with asynchronous calls, which are useful for making API requests, for example. Promises have a major limitation in that they're only useful for one call cycle. For example, if you wanted to have a promise return a value on an event like a user click, that promise would resolve on the first click. But you might be interested in handling every user click action. Normally, you'd use an event listener for this, and that allows you to handle events over time. This is an important distinction: Observables are like event handlers in that they continue to process data over time and allow you to continuously handle that stream of data.
Promise是另一种帮助处理异步调用的结构,例如,它对于发出 API 请求很有用。Promises 有一个主要的限制,因为它们只对一个调用周期有用。例如,如果您希望承诺在用户单击等事件上返回一个值,则该承诺将在第一次点击时解决。但是您可能对处理每个用户点击操作感兴趣。通常,您会为此使用事件侦听器,这允许您随时间处理事件。这是一个重要的区别:Observable 就像事件处理程序,因为它们会随着时间的推移继续处理数据,并允许您连续处理该数据流。
回答by Masoud Bimar
When you understand Observable
s correctly, the differences to Promise
s are pretty obvious.
当您Observable
正确理解s 时,与 s 的区别Promise
非常明显。
The best way to demystify a convoluted concept is to implement it from scratch. Here is an almost purely functional Observable
implementation and an example, that wouldn't work with Promise
s:
揭开一个复杂概念的神秘面纱的最好方法是从头开始实施它。这是一个几乎纯函数式Observable
实现和一个示例,它不适用于Promise
s:
/*** Observable type ***/
// type constructor (of a product type)
const proType = name => cons => {
const f = (k, ...args) =>
Object.defineProperties({["run" + name]: k}, {
[Symbol.toStringTag]: {value: name},
[Symbol("args")]: {value: args}
});
return cons(f);
};
// value constructor
const Observable = proType("Observable")
(Observable => k => Observable(k));
/*** Observer factory ***/
const Observer = observer => {
let isUnsubscribed = false;
return {
next: function(x) {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
return observer.next(x);
}
catch(e) {
isUnsubscribed = true;
this.cancel();
throw e;
}
}
},
error: function(e) {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
return observer.error(e);
}
catch(e_) {
isUnsubscribed = true;
this.cancel();
throw e_;
}
}
},
complete: function() {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
const r = observer.complete();
this.cancel();
return r;
}
catch(e) {
isUnsubscribed = true;
cancel();
throw e;
}
}
}
};
};
/*** combinators + auxiliary functions ***/
const subscribe = observable => handlers => {
const observer = Observer(handlers),
cancel = observable.runObservable(observer);
observer.cancel = cancel;
return cancel;
};
const obsMap = f => observable =>
Observable(observer => {
const mapObserver = {
next: x => observer.next(f(x)),
error: e => observer.error(e),
complete: () => observer.complete()
};
return observable.runObservable(mapObserver);
});
/*** main ***/
// create an Observable instance
const numStream = Observable(observer => {
let i = 0;
const timer = setInterval(() => {
observer.next(i++);
}, 1000);
return () => clearTimeout(timer);
});
// map a function over it
const squaredNumStream =
obsMap(x => x * x) (numStream);
// run the observable
const cancel = subscribe(squaredNumStream) ({
next: x => console.log(x),
error: e => console.error(e),
complete: () => console.log("finished")
});
// cancel it
setTimeout(cancel, 11000);
In the example above the Observable
squaredNumStream
emits a stream of theoretically infinite values asynchronously. You cannot do this with Promise
s, because they represent a single future value.
在上面的示例中,Observable
squaredNumStream
异步发出理论上无限值的流。你不能用Promise
s来做这件事,因为它们代表一个单一的未来值。
I could have easily subscribed to another squaredNumStream
without both instances interfering with each other. This is because Observable
s are unicast, whereas Promise
s are multicast.
我可以很容易地订阅另一个squaredNumStream
实例而不会相互干扰。这是因为Observable
s 是单播的,而Promise
s 是多播的。
squaredNumStream
doesn't run at declaration time, but only after subscription, because Observable
s are lazily evaluated. Promise
s on the other hand are eagerly evaluated that is, they start running as soon as you create them.
squaredNumStream
不在声明时运行,而只在订阅后运行,因为Observable
s 是惰性求值的。Promise
另一方面,s 会被急切地评估,也就是说,一旦您创建它们,它们就会开始运行。
And finally, Observable
s are cancelable by design, whereas Promise
s are hard to cancel due to there unicast semantics.
最后,Observable
s 在设计上是可取消的,而Promise
s 由于存在单播语义而难以取消。