等待Angular 4中的订阅和承诺

时间:2017-08-21 14:37:14

标签: 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 => {
            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
}

在客户端,我需要进行另一次服务器调用,但只有当我有来自上述两个调用的数据时。换句话说,我需要Subscription来完成(好,不完整但设置值)并完成Promise

是否有类似Promise.all的内容可以确保在this.model来电中设置Subscription

编辑: 我可以连续运行这些,但出于性能原因,我想并行运行它们。

编辑2: Promise旨在加载查找数据以仅填充一次下拉列表。 Subscription旨在更改" id"的每次更改时的主模型。在网址中。

3 个答案:

答案 0 :(得分:3)

  1. 对promise和模型提取observable使用.zip()。它将输出一组结果,您可以使用这些结果填充本地类属性。此时,您可以调用第3个函数(本地过滤器)。一旦承诺完成,.zip也将如此,因此该链只有一个输出。

  2. .zip()完成后,请收听新路由参数并获取相应的模型。当他们到达时,设置您的本地类属性并运行本地过滤器

  3. 订阅以触发整个链。

    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();
        })
    }
    
  4. Live demo

答案 1 :(得分:2)

您可以使用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运算符:

About Observable.combineLatest

由于每当其中一个源可观察对象发出时它就会发出,因此将执行订阅块。由于另一个observable来自一个promise,它将完成而不会发出更多值,因此不会再调用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
            });

答案 2 :(得分:0)

您可以执行类似

的操作
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