Promise Chaining / Cascading to RxJS angular 1 to angular 2
Posted
技术标签:
【中文标题】Promise Chaining / Cascading to RxJS angular 1 to angular 2【英文标题】: 【发布时间】:2016-11-30 01:59:49 【问题描述】:我目前正在尝试将一些好的旧 $http Promises 转换为 angular2 中的 rxJs observables。
一个非常简单的例子,我过去经常在 Angular 1 中做的事情:
// Some Factory in Angular 1
var somethings = [];
var service =
all: all
;
return service;
function all()
return $http
.get('api/somethings')
.then(function(response)
somethings = parseSomethings(response.data);
return somethings;
);
// Some Controller in Angular 1
var vm = this;
vm.somethings = [];
vm.loading = true;
loadThings();
function loadThings()
SomeFactory
.all()
.then(function(somethings)
vm.somethings = somethings;
)
.finally(function()
vm.loading = false;
)
现在我可以使用 RxJs Observable 和 Subject 实现与 angular2 类似的功能。但我不确定如何将“完成挂钩”返回给调用者。 (例如:angular1 控制器中的加载)
我对 angular2 的尝试是类似的:
// Some Service in Angular 2
export class SomeService
private _somethings$: Subject<Something[]>;
private dataStore:
somethings: Something[]
;
constructor(private http: Http)
get _somethings$() : Observable<Something[]>
return this._somethings$.asObservable();
loadAll()
this.http
.get(`api/somethings`)
.map(response => response.json())
.subscribe(
response =>
this.dataStore.somethings = parseSomethings(response.data);
this._somethings$.next(this.dataStore.somethings);
);
//Some Component in Angular 2
export class SomeComponent()
constructor(private someService: SomeService)
ngOnInit()
this.someService.loadAll();
this.somethings = this.someService.somethings$;
注意
我在这里使用了 Subject / Observable,这样当我创建/更新/删除“某物”时,我可以调用 .next 来通知订阅者。
例如:
create(something: Something) : Observable<Something>
return this.http.post(`api/somethings`, JSON.stringify(something))
.map(response => response.json())
.do(
something =>
this.dataStore.somethings.push(something);
this._somethings$.next(this.dataStore.somethings); //Notify the subscribers
);
注意
这里我在方法中使用了 .do,当在“表单组件”中调用该方法时,我订阅只是为了获取完成处理程序:
this.someService.create(something).subscribe(
(ok) => ...
(error) => ...
() => stop loading indicator
)
问题
我们如何在 Angular 2 中使用 RxJs 将完成挂钩传递给调用者(例如 angular 1 控制器) 存在哪些替代路径来实现类似行为?【问题讨论】:
嘿,我对 AngularJS 不太熟悉。但据我了解,您想知道get
函数何时完成以将loading
设置为false?在这种情况下,请将您的服务中的 subscribe
块移动到您的组件并在那里设置 loading
标志。
好的,我是否应该在组件中取消订阅(可以在单击按钮调用 create.subscribe() 之后说)
不,http.get
和 http.post
将在返回响应后完成,因此您无需 unsubscribe
他们。
很好,感谢您的澄清
【参考方案1】:
您的最后一个代码示例很好。只需使用map()
而不是subscribe()
并在呼叫站点订阅。
你可以使用
return http.post(...).toPromise(val => ...))
或
return http.post(...).map(...).toPromise(val => ...))
获得与 Angular 中相同的行为,您可以使用 .then(...)
链接后续调用
【讨论】:
我在考虑使用地图 aswel。 .do 适合这个 aswel 吗?map()
返回的值转发给订阅者。如果您不想修改该值而只是对每个事件造成一些副作用,那么do()
也可以。
我可以假设多个 .map 调用只会像 .then 那样 cascade
吗?
没错。您可以级联各种运算符,也可以多次级联。仅subscribe()
最后只能执行一次。以上是关于Promise Chaining / Cascading to RxJS angular 1 to angular 2的主要内容,如果未能解决你的问题,请参考以下文章