使用 Javascript 进行反应式编程
Posted
技术标签:
【中文标题】使用 Javascript 进行反应式编程【英文标题】:Reactive programming with Javascript 【发布时间】:2016-06-29 03:51:47 【问题描述】:我是响应式编程的新手,阅读所有这些我无法理解的文章我有点迷茫。
实际上,我是一名来自 Nodejs、Angularjs、Angular 2 和 React 的 javascript 开发人员。
我做什么
我一直使用 Promise,用于远程数据获取、本地异步解析等...比回调更好的可测试性并满足我的需求。
我对流的理解
我不知道流在哪里可以拯救我,除非在特殊情况下。
这种特殊情况是我不能在监听流时使用 Promise,因为 Promise 只会被解析一次。
SocketIo 示例:
io.on('connection', (socket) =>
// this works
);
io.on('connection').then((socket) =>
// this can't work, promise would be resolved only once
);
如果我没记错的话,我可以通过简单地返回一个 observable 来使用响应式流来管理这种情况。对吧?
我不明白的地方
我正在研究 Angular 2 和周围的所有东西。实际上,在许多博客中,人们习惯于使用 observables 来获取远程数据,我无法理解使用它而不是 promises 有什么优势。
事实上,在这两种情况下我都需要制作一个遥控器,那么为什么一个比另一个多呢?这是性能问题吗?
我需要什么
如果您已经阅读了整个问题,我需要了解在远程数据获取的情况下使用响应式编程而不是 Promise 的优势是什么?
在哪些情况下(其他情况)使用反应性的东西比使用普通的东西更好?
【问题讨论】:
阅读本期,会澄清很多github.com/angular/angular/issues/5876 【参考方案1】:基本上,如果您有一个异步事件,您不想收到有关(回调)的通知,您可以使用Promise
。如果您预计会发生一系列事件,请使用Observable
Observable
相对于Promise
的优势
Observable
才能让您以相同的方式编写代码(使用 rx 运算符而不是 .then()
,无论您期待一个或一系列事件。
【讨论】:
嗨!我知道这是一个古老的答案,但我可能不清楚一件事。 observables 是否可以为以后的订阅者保留返回值,类似于已经解决的承诺将立即成为.then()
d?此外,您能否在不影响其操作的情况下拥有多个订阅者来订阅 observable(例如,进行两次异步调用)如果您认为值得提出自己的问题,我可以这样做。
BehaviorSubject
创建一个Observable
,它会立即将最后一个值返回给新订阅者。 .share()
操作员进行Observable
多播,每个事件都传递给每个订阅者。注意 - 您需要显式导入运算符(如 map
、share
、...)。【参考方案2】:
@Günter 为您提供了 observables 的基础,尤其是调用 Promise 的能力。
更进一步,我认为 observables 的主要优势是能够使用运算符构建异步数据流/流。
以下是一些具体的用例:
debounceTime
/switchMap
。当您想利用表单输入根据相应的 HTTP 请求过滤列表时,您需要用于请求的值是用户完成写入时的值。不必发送多个请求:每个新字符一个(一个用于“s”,一个用于“so”,一个用于“som”,...,一个用于“搜索的东西”)。 debounceTime
运算符通过缓冲事件来实现这一点,并在一段时间不活动后提供最后一个事件。
这是一个示例:
@Component(
(...)
template: `
<input [ngFormControl]="ctrl"/>
`
)
export class MyComponent
constructor()
this.ctrl = new Control();
this.ctrl.valueChanges
.debounceTime(500)
.distinctUntilChanged()
.switchMap((vallue: string) =>
// Get data according to the filled value
return this.service.getData(entry);
)
.subscribe(data =>
// Update the linked list
this.list = data;
);
如果您只使用switchMap
,则每个输入将有一个请求,但之前正在进行的请求将被取消。这可以让您获得正确的结果,尤其是在某些请求的请求执行时间较长的情况下。
在这种情况下,您可以将 Web UI 中的事件(DOM 事件)链接到 HTTP 请求以相应地执行(对事件做出反应)并应用一些高级行为。
实施重试。通过混合retryWhen
、delay
和timeout
运算符,您可以轻松(且透明地)实现重试
searchPlaces(searchText:string)
var params = new URLSearchParams();
params.set('placename_startsWith', searchText);
params.set('username', 'templth');
return this.http.get('http://api.geonames.org/postalCodeSearchJSON',
search: params )
.retryWhen(error => error.delay(500))
.timeout(2000, return new Error('delay exceeded'))
.map(res => res.json().postalCodes);
我认为这就是 observables 的真正力量:异步处理链/数据流并基于事件链接应用程序的不同部分。这是使用 Promise 无法完成的事情,并且允许实现用例以使您的应用程序更加健壮。
这里有一系列文章可以为您提供更多详细信息:
https://jaxenter.com/reactive-programming-http-and-angular-2-124560.html http://slides.com/robwormald/everything-is-a-stream https://gist.github.com/staltz/868e7e9bc2a7b8c1f754【讨论】:
以上是关于使用 Javascript 进行反应式编程的主要内容,如果未能解决你的问题,请参考以下文章