JavaScript 中的 observable 和 promises 之间有什么区别?
What are the differences between observables and promises in JavaScript?
所以我读到,在一些即将推出的 JavaScript MVC 中,可观察对象正在寻求在使用方面超越承诺:
observables 和 promises 有什么区别?
更新:抱歉!删除了我的虚假声明。
What is the difference between observables and promises?
简单地说:一个 promise 异步解析为一个 单个 值,一个 observable 异步解析(或发出)多个 值(超过时间)。
具体例子:
- 承诺:来自 Ajax 调用的响应
- 可观察:点击事件
可在此处找到更多信息:http://reactivex.io/intro.html
i've read that observables are looking to overtake promises
不太可能。 Observables 可能是某些问题的更好解决方案,但这并没有使承诺过时(如果那是你的意思)。
Promises 表示 1 个未来值。
Observables 是对可能无限数量的值的表示。
Promises 将在创建后立即触发获取该值。
Observables 只有在您订阅它们时才会开始产生值。 (除非它是一个热门的可观察对象,但这超出了这个问题的范围)
Promises 旨在表示 AJAX 调用。
Observable 旨在表示任何事物:事件、来自数据库的数据、来自 ajax 调用的数据、(可能是无限的)序列等
Promises 提供了一种非常简单的回调机制,而 Rx 提供了对异步编程的强大抽象。 Observable 代表数据流,然后我们可以对其应用运算符以定义应如何处理传入数据。
如果您需要做的只是发出一个 HTTP 请求,然后更新一个 UI 组件,那么使用 Promise 可能就足够了。
然而,大多数应用往往有比这更复杂的需求(即使一开始并不明显)。以我们的 HTTP 请求为例,让我们看看将其建模为 Observable 并使用一些 Rx 运算符如何帮助我们:
-如果 HTTP 请求是由用户操作触发的,我们可能要小心触发多个 HTTP 请求(假设用户在搜索框中键入内容)。我们不想在每次击键时都触发请求,因此我们可能希望 限制 我们的搜索,以便我们仅在用户停止输入 300 毫秒后才触发请求。此外,如果用户键入一个词,等待 300 毫秒,然后添加另一个字符,我们将触发后续的 HTTP 请求。使用 Promises,我们可能会遇到竞争条件,因为我们无法控制接收响应的顺序,也无法取消旧请求。 Rx 通过允许我们在流之间 Switch 来解决这个问题,这会在我们不再关心的旧请求订阅上调用 Dispose。我们也可能会过滤掉任何无效的搜索输入,例如 其中 搜索词的长度少于 3 个字符。
-支持处理Timeouts/Error处理。假设我们的 HTTP 请求失败,Rx 允许我们轻松地 重试 发出请求。
-假设我们的应用程序的几个部分需要进行相同的 HTTP 调用,我们可能不想实际进行多次调用。我们可以将我们的可观察对象暴露给多个消费者,并使用 Replay 来确保调用一次并为后续订阅者缓存结果。我们甚至可以提供一个 TimeSpan 来重播,让我们过期缓存行为。
-通过使用调度程序对线程进行强大的抽象,这使我们能够控制并发性。更好的是,我们可以在我们的单元测试中使用测试调度程序来控制时间,允许我们模拟超时、竞争条件等。
这些是一些简单的例子来演示什么是可能的。 Rx 框架中有更多的操作符来满足所有类型的场景,Rx 的可组合性意味着您可以轻松组合操作符来定义您需要的行为。创建自己的可重用运算符(例如 RetryAfterDelay)也很容易。
总而言之,Rx 可以做的一切都比 Promises 可以做,而且远不止于此。我怀疑在接下来的几年里,将继续转向 Rx 而不是 Promises。
如需进一步阅读,我建议您查看 Angular 2 guide 中有关 Observable 的部分。
中所述
当您想要获取单个数据块时,转换为 Promise 通常是一个不错的选择。所以当你收到数据时,你就完成了。
但在某些情况下,请求并不总是只完成一次。您可以启动一个请求,取消它,然后在服务器完成之前发出另一个请求
响应了第一个请求。
例如在搜索组件中 当用户在搜索框中键入名称时,您将通过该搜索查询发出重复的 HTTP 请求。
A request-cancel-new-request sequence is difficult to implement with
Promises, but easy with Observables.
因此,如果您的组件仅通过一个请求获取数据,那么使用 Promise
是一个不错的选择,但如果它有一系列请求-取消-新请求,您应该使用 observable
Observables 通常被比作 promises。以下是一些主要区别:
Observable 是声明性的;计算直到订阅才开始。 Promise 在创建时立即执行。这使得 observables 对于定义食谱很有用,只要您需要结果,就可以 运行。
Observables 提供了很多价值。承诺提供了一个。这使得 observables 对于随时间获取多个值很有用。
Observables 区分链接和订阅。 Promise 只有 .then() 子句。这使得可观察对象可用于创建供系统其他部分使用的复杂转换配方,而不会导致工作被执行。
Observables subscribe() 负责处理错误。承诺将错误推送给子承诺。这使得 observables 对于集中和可预测的错误处理很有用。
官方网站angular的最佳解释:
当您正确理解 Observable
时,与 Promise
的区别非常明显。
揭开复杂概念神秘面纱的最好方法是从头开始实施它。这是一个几乎纯功能性的 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);
在上面的示例中,Observable
squaredNumStream
异步发出理论上无限值的流。您不能对 Promise
执行此操作,因为它们代表单个未来值。
我本可以轻松订阅另一个 squaredNumStream
,而不会相互干扰。这是因为 Observable
是单播,而 Promise
是多播。
squaredNumStream
在声明时不会 运行,但仅在订阅后才会,因为 Observable
是延迟计算的。另一方面,Promise
s 是急切求值的,也就是说,它们会在您创建它们后立即开始 运行ning。
最后,Observable
可以通过设计取消,而 Promise
由于存在单播语义,因此很难取消。
Observables VS。承诺(杰里米·维尔肯)
除了新语法,observables 是 JavaScript 应用程序的新模式
管理异步活动。它们也是在 JavaScript 语言中本地实现的一项功能的草案,因此它在模式背后具有重要意义。 RxJS 是
我们将用来帮助我们在应用程序中实现可观察对象的库。
Promises 是另一种有助于处理异步调用的结构,很有用
例如,用于发出 API 请求。 Promise 有一个主要的限制,因为它们是
仅对一个调用周期有用。例如,如果你想要一个 promise return a
用户点击等事件的价值,该承诺将在第一次点击时解决。但是您可能对处理每个用户点击操作感兴趣。通常,您会使用一个事件
为此的监听器,这使您可以随着时间的推移处理事件。这是一个重要的区别:Observables 就像事件处理程序一样,它们继续处理数据
时间并允许您持续处理该数据流。
所以我读到,在一些即将推出的 JavaScript MVC 中,可观察对象正在寻求在使用方面超越承诺:
observables 和 promises 有什么区别?
更新:抱歉!删除了我的虚假声明。
What is the difference between observables and promises?
简单地说:一个 promise 异步解析为一个 单个 值,一个 observable 异步解析(或发出)多个 值(超过时间)。
具体例子:
- 承诺:来自 Ajax 调用的响应
- 可观察:点击事件
可在此处找到更多信息:http://reactivex.io/intro.html
i've read that observables are looking to overtake promises
不太可能。 Observables 可能是某些问题的更好解决方案,但这并没有使承诺过时(如果那是你的意思)。
Promises 表示 1 个未来值。 Observables 是对可能无限数量的值的表示。
Promises 将在创建后立即触发获取该值。 Observables 只有在您订阅它们时才会开始产生值。 (除非它是一个热门的可观察对象,但这超出了这个问题的范围)
Promises 旨在表示 AJAX 调用。 Observable 旨在表示任何事物:事件、来自数据库的数据、来自 ajax 调用的数据、(可能是无限的)序列等
Promises 提供了一种非常简单的回调机制,而 Rx 提供了对异步编程的强大抽象。 Observable 代表数据流,然后我们可以对其应用运算符以定义应如何处理传入数据。
如果您需要做的只是发出一个 HTTP 请求,然后更新一个 UI 组件,那么使用 Promise 可能就足够了。
然而,大多数应用往往有比这更复杂的需求(即使一开始并不明显)。以我们的 HTTP 请求为例,让我们看看将其建模为 Observable 并使用一些 Rx 运算符如何帮助我们:
-如果 HTTP 请求是由用户操作触发的,我们可能要小心触发多个 HTTP 请求(假设用户在搜索框中键入内容)。我们不想在每次击键时都触发请求,因此我们可能希望 限制 我们的搜索,以便我们仅在用户停止输入 300 毫秒后才触发请求。此外,如果用户键入一个词,等待 300 毫秒,然后添加另一个字符,我们将触发后续的 HTTP 请求。使用 Promises,我们可能会遇到竞争条件,因为我们无法控制接收响应的顺序,也无法取消旧请求。 Rx 通过允许我们在流之间 Switch 来解决这个问题,这会在我们不再关心的旧请求订阅上调用 Dispose。我们也可能会过滤掉任何无效的搜索输入,例如 其中 搜索词的长度少于 3 个字符。
-支持处理Timeouts/Error处理。假设我们的 HTTP 请求失败,Rx 允许我们轻松地 重试 发出请求。
-假设我们的应用程序的几个部分需要进行相同的 HTTP 调用,我们可能不想实际进行多次调用。我们可以将我们的可观察对象暴露给多个消费者,并使用 Replay 来确保调用一次并为后续订阅者缓存结果。我们甚至可以提供一个 TimeSpan 来重播,让我们过期缓存行为。
-通过使用调度程序对线程进行强大的抽象,这使我们能够控制并发性。更好的是,我们可以在我们的单元测试中使用测试调度程序来控制时间,允许我们模拟超时、竞争条件等。
这些是一些简单的例子来演示什么是可能的。 Rx 框架中有更多的操作符来满足所有类型的场景,Rx 的可组合性意味着您可以轻松组合操作符来定义您需要的行为。创建自己的可重用运算符(例如 RetryAfterDelay)也很容易。
总而言之,Rx 可以做的一切都比 Promises 可以做,而且远不止于此。我怀疑在接下来的几年里,将继续转向 Rx 而不是 Promises。
如需进一步阅读,我建议您查看 Angular 2 guide 中有关 Observable 的部分。
当您想要获取单个数据块时,转换为 Promise 通常是一个不错的选择。所以当你收到数据时,你就完成了。
但在某些情况下,请求并不总是只完成一次。您可以启动一个请求,取消它,然后在服务器完成之前发出另一个请求 响应了第一个请求。
例如在搜索组件中 当用户在搜索框中键入名称时,您将通过该搜索查询发出重复的 HTTP 请求。
A request-cancel-new-request sequence is difficult to implement with Promises, but easy with Observables.
因此,如果您的组件仅通过一个请求获取数据,那么使用 Promise
是一个不错的选择,但如果它有一系列请求-取消-新请求,您应该使用 observable
Observables 通常被比作 promises。以下是一些主要区别:
Observable 是声明性的;计算直到订阅才开始。 Promise 在创建时立即执行。这使得 observables 对于定义食谱很有用,只要您需要结果,就可以 运行。
Observables 提供了很多价值。承诺提供了一个。这使得 observables 对于随时间获取多个值很有用。
Observables 区分链接和订阅。 Promise 只有 .then() 子句。这使得可观察对象可用于创建供系统其他部分使用的复杂转换配方,而不会导致工作被执行。
Observables subscribe() 负责处理错误。承诺将错误推送给子承诺。这使得 observables 对于集中和可预测的错误处理很有用。
官方网站angular的最佳解释:
当您正确理解 Observable
时,与 Promise
的区别非常明显。
揭开复杂概念神秘面纱的最好方法是从头开始实施它。这是一个几乎纯功能性的 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);
在上面的示例中,Observable
squaredNumStream
异步发出理论上无限值的流。您不能对 Promise
执行此操作,因为它们代表单个未来值。
我本可以轻松订阅另一个 squaredNumStream
,而不会相互干扰。这是因为 Observable
是单播,而 Promise
是多播。
squaredNumStream
在声明时不会 运行,但仅在订阅后才会,因为 Observable
是延迟计算的。另一方面,Promise
s 是急切求值的,也就是说,它们会在您创建它们后立即开始 运行ning。
最后,Observable
可以通过设计取消,而 Promise
由于存在单播语义,因此很难取消。
Observables VS。承诺(杰里米·维尔肯)
除了新语法,observables 是 JavaScript 应用程序的新模式 管理异步活动。它们也是在 JavaScript 语言中本地实现的一项功能的草案,因此它在模式背后具有重要意义。 RxJS 是 我们将用来帮助我们在应用程序中实现可观察对象的库。
Promises 是另一种有助于处理异步调用的结构,很有用 例如,用于发出 API 请求。 Promise 有一个主要的限制,因为它们是 仅对一个调用周期有用。例如,如果你想要一个 promise return a 用户点击等事件的价值,该承诺将在第一次点击时解决。但是您可能对处理每个用户点击操作感兴趣。通常,您会使用一个事件 为此的监听器,这使您可以随着时间的推移处理事件。这是一个重要的区别:Observables 就像事件处理程序一样,它们继续处理数据 时间并允许您持续处理该数据流。