Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 在第4节中等待订阅和承诺_Angular_Typescript_Promise_Rxjs - Fatal编程技术网

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 => {

我对Angular 4还不熟悉,所以我接受改变我的方法可能会更好

我所拥有的是:

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
            });
  • 对promise和获取observable的模型使用
    .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.Nice
    CombineTest()
    是此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()更新后与每个新参数一起运行。我已经重写了我的答案并提供了一个演示。如果你决定了一个更好的解决方案,请教给我们!