我很难将我的大脑缠绕在Angular的观察者身上 . 我来自PHP的世界,事情肯定不是异步的 .
我有一个组件,只显示一般主题的消息列表 . 现在,我有一个所有消息都属于的主题 . 如果主题不存在,则应创建该主题 . 消息和主题调用都是通过REST API完成的 .
在非同步世界中,我会按顺序编程 . 消息服务将查看主题是否存在 . 如果没有,那么它有主题服务创建它 . 在有主题后,它会获取该主题中的所有消息 .
我知道你订阅了一个observable,但是当需要按顺序发生一系列事情时会发生什么? angular 2 http documentation经历了一个非常简单的例子,即在进行一次调用时更新英雄列表 .
Component
export class NotificationListComponent implements OnInit {
constructor(private _notificationService:NotificationService) {
}
***
ngOnInit() {
this.getNotifications();
}
getNotifications() {
this._notificationService.getNotifications()
.subscribe(
notifications => this.notifications = notifications,
error => this.errorMessage = <any>error);
}
Notification Service
...
getNotifications() {
// call the topic service here for general topic??
return this.http.get('/messages?order[datesent]=DESC')
.map((res) => {
return res.json()["hydra:member"];
})
.map((notifications:Array<any>) => {
let result:Array<Notification> = [];
notifications.forEach((jsonNotification) => {
var Notification:Notification = {
message: jsonNotification.message,
topic: jsonNotification.topic,
datesent: new Date(jsonNotification.datesent),
};
result.push(Notification);
});
return result;
})
.catch(this.handleError);
}
...
Topic Service
...
getGeneralTopic() {
var generalTopic;
this.http.get('/topics?name=general')
.map((res) => {
return res.json()["hydra:member"][0];
})
.do(data => console.log(data))
.subscribe(generalTopic => res);
}
...
3 回答
如何推理Observables?
Observable处理流 . 流可以是几乎任何东西,但你可以把它们想象成 abstract array of asynchronous events . 这很有用,因为您现在可以更清楚地推理它们:
abstract 因为Observable可以生成任何类型的值:
String, Boolean, Object
array 因为Observable的Operators与JavaScript的数组方法类似:
map(), filter(), reduce()
of 因为Observable是值的包装器
asynchronous 因为Observable可能会也可能不会执行
events 因为需要触发Observable
何时使用Observables?
您通常在需要执行任务或涉及多个步骤的操作时使用Observable . 这可以作为您的起点,您可以根据需要简化或增加复杂性 .
你应该有一个“计划”或至少一个模糊的想法,这些步骤应该是什么 . 听起来很明显,但很多问题都出现了,因为你不知道自己想要什么(;
一旦你计划了一个动作(作为一系列步骤),你可以从任何一端开始,但我认为最好从最后开始 . 至少在你了解更多之前 .
对于您的用例 The Plan 将是:
["(create topic)", "select topic", "show messages"]
.messages
是 abstract array ,select
和create
是 asynchronous events .如何使用Observable?
正如我上面所说,让我们从最后开始 -
"show messages"
.我们知道我们正在处理
Observable.of(messages)
(这是你手动创建它的方式) . 接下来,您需要'fill'消息流,您可以使用返回Observable
的Http
服务来执行此操作 . 由于您从服务器获得的消息包含在多个"layers"服务中,因此我们可以利用Observable的功能来链接运算符(运算符返回Observable
)并获取我们需要的消息:你可以使用你需要的任何Operators这导致了Observables的下一个重大事件:
“热”和“冷”可观测量
默认情况下,Observable是 cold . 这意味着当您创建一个observable时,您只需描述它应该做什么 . 它不会立即执行这些操作(如
Promises
)它需要被触发 .你可以通过订阅它来触发它,或者使用
subscribe()
方法手动触发它,或者你可以让Angular使用async
pipe(它订阅你)使它成为 hot .注意变化
接下来要做的事情(或之前因为我们将在 The Plan 中倒退)是
"select topic"
. 观看所选主题的 Value 并通过加载新消息来响应它的变化会很好 . 这可以通过Subject来完成 .我们可以设置
topic$
这样做:总结
最后一步是
"(create topic)"
如果没有't exist. Let'假设服务器会在主题不存在时返回错误:这是这个例子的working plunker . 正如你所看到的那样,这并不难(50行代码......) . 您可以轻松移动物品并根据需要创建服务 .
实际上,Reactive Programming允许创建异步数据流 . 这意味着你可以利用
Angular2的HTTP支持利用运算符(flatMap,...)将流链接在一起并实现复杂的处理链 . 这意味着您可以使用Reactive Programming / RxJS的所有概念将HTTP请求作为异步数据流的一部分 .
这里有一个简单的示例,它允许根据表单输入的值执行请求(发生更新时):
操作员还可以在HTTP上下文中轻松实现几个问题:
switchMap
运算符的示例,用于在触发新请求时取消先前正在进行的请求以下是一些有关反应式编程的文章可以帮助您:
AndréStaltz一直缺少Reactive Programming的介绍 - https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
一切都是Rob Wormald的流 - http://slides.com/robwormald/everything-is-a-stream
虽然我不太明白你的问题,但可能
Observable.selectMany
和Observable.and/thenDo/when
可以帮助你 .https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/selectmany.md
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/when.md
在您的情况下,我认为它可以让您创建一个提取和插入的事务 .