Angular 在第4节中等待订阅和承诺
我对Angular 4还不熟悉,所以我接受改变我的方法可能会更好 我所拥有的是:Angular 在第4节中等待订阅和承诺,angular,typescript,promise,rxjs,Angular,Typescript,Promise,Rxjs,我对Angular 4还不熟悉,所以我接受改变我的方法可能会更好 我所拥有的是: ngOnInit() { this.route.paramMap .switchMap((params: ParamMap) => { var id = +params.get('id'); return this.service.getOne(id); }).subscribe(data => {
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) => {
var id = +params.get('id');
return this.service.getOne(id);
}).subscribe(data => {
if (data.clientID === 0) {
data.clientID = +this.route.snapshot.queryParams["parentId"];
}
this.model = data;
},); // Subscription
this.lookupService.getList("clients").then(data => {
this.clients = data;
}); // Promise
}
在客户端,我需要进行另一个服务器调用,但仅当我从上述两个调用中都获得了数据时。换句话说,我需要订阅
完成(当然,不是完成,而是设置值)和承诺
完成
是否有类似于承诺的东西。所有
都可以确保此模式
已在订阅
呼叫中设置
编辑:
我可以将它们串联运行,但出于性能原因,我希望将它们并联运行
编辑2:
Promise
旨在加载查找数据以仅填充一次下拉列表。订阅
旨在每次更改URL中的“id”时更改主模型。您可以执行以下操作
ngOnInit() {
this.lookupService.getList("clients").then(data => {
this.clients = data;
this.route.paramMap
.switchMap((params: ParamMap) => {
var id = +params.get('id');
return this.service.getOne(id);
}).subscribe(data => {
if (data.clientID === 0) {
data.clientID = +this.route.snapshot.queryParams["parentId"];
}
this.model = data;
==>Call ur method here!!!
},); /
}); // Promise
您可以使用
Observable.forkJoin
,它相当于Promise.all
Observable.forkJoin(this.route.paramMap
.switchMap((params: ParamMap) => {
var id = +params.get('id');
return this.service.getOne(id);
}), Observable.fromPromise(this.lookupService.getList("clients")))
.subscribe((arrayOfResults) => {
[firstCallResult, secondCallResult] = arrayOfResults;
this.model = firstCallResult;
});
编辑:
为了完成有关更新参数的部分,我们可以使用Observable.combineLatest
操作符:
由于每当一个源可观测物发射时,它就会发射,因此将执行subscribe块。由于另一个可观察对象来自承诺,因此它将完成并且不会发出更多值,因此不会再次调用this.lookupService.getList()
Observable.combineLatest(this.route.paramMap
.switchMap((params: ParamMap) => {
var id = +params.get('id');
return this.service.getOne(id);
}), Observable.fromPromise(this.lookupService.getList("clients")))
.subscribe((arrayOfResults) => {
[firstCallResult, secondCallResult] = arrayOfResults;
this.model = firstCallResult;
// do whatever else is needed
});
.zip()
。它将输出一个结果数组,可用于填充本地类属性。此时,您可以调用第三个函数(本地过滤器)。一旦承诺完成,那么.zip
,因此此链只有一个输出.zip()
后,收听新的路由参数并获取相应的模型。当它们到达时,设置本地类属性并运行本地筛选器ngOnInit(){
// Will run getOne() with every new parameter
let getModelForParam = this.route.paramMap.switchMap(
params => this.service.getOne(+params.get('id'))
).share();
// Zip will wait for both below to produce, then output an array of results
// and complete (since getList() promise completes after one call)
Observable.zip(
this.lookupService.getList('clients'),
getModelForParam
).do(results => { // capture results in order of .zip() arguments
this.clients = results[0];
this.model = results[1];
this.localFilter();// call the filter
}).concat( // this part executes once .zip() completes
getModelForParam // continue fetching models for new params
).subscribe(model => {
this.model = model;
this.localFilter();
})
}
我会更新这个问题,但我不想连续运行这些服务器调用。我们的“服务层”有几十个对象返回承诺(如angular.io教程中的承诺)并进行更改,这将对全球产生影响。但是,如果这是唯一的方法,那么我想我需要这样做。@KevinWelsh查看我的编辑。您可以使用
Observable.fromPromise()
将承诺转换为Observable.NiceCombineTest()
是此I的正确运算符think@Matsura,CombineTest()
工作得很好。谢谢。我相信switchMap
不会完成,因为该组件可以重用,并且您不能使用take(1)
,因为如果该组件损坏,您将丢失对参数的所有以下更新reused@MaximKoretskyi有趣的问题。我想你是对的。因为这可能意味着每次发出一个新参数时都要运行,所以我们不应该在1个结果之后停止。更好的方法是使用zip
。它还将并行调用,但仅在两个响应到达时发出。我会更新我的答案。@MaximKoretskyi事实上,现在我想起来了,OP有一个结果,它是一个承诺决议,意味着一个和完成。因此,如果要求在前两个结果到达后进行第三次调用,则第三次调用将只发生一次(因为承诺只解决一次)。因此,在实践中,我看不出forkJoin/take(1)
和zip
Thank@belletJuice之间的区别。不过,我确实需要未来的通知,在地图上。但是我不需要每次都重新加载this.lookupService.getList(“客户机”)
。此外,我还尝试了您的代码示例,this.route.paramMap.switchMap(“…”)
的省略号中的代码从不运行。我将这2个添加到文件的顶部:import{Observable}from“rxjs/Observable”;导入'rxjs/add/operator/zip'
@KevinWelsh,那么您想在每次参数更改时只运行一次this.lookupService.getList
,但this.service.getOne(id)
然后在每次参数更改时连接结果并发出新项吗?所以lookupService.getList()
应该只运行一次service.getOne()
应该在每次新参数到达时运行,对吗?好的,第三个电话呢?你说应该等另外两个生产出来,但是第一个生产出来之后呢?第三个调用应该只执行一次还是每次新参数到达时执行?我已经将第三个调用简化为只运行本地筛选函数,但它需要在service.getOne()更新后与每个新参数一起运行。我已经重写了我的答案并提供了一个演示。如果你决定了一个更好的解决方案,请教给我们!