将多个嵌套的Promise和Promise数组转换为Observables

时间:2018-12-19 13:05:37

标签: javascript angular typescript promise

我正在将TypeScript中的AngularJS应用转换为Angular 7。

在将一些复杂的嵌套承诺转换为Observables时遇到一些问题。

以下是我正在处理的代码的示例:

signup.component.js

function SomethingSignupController(somethingApplication) {
    function activate() {
        getApplication();
    } 

    function getApplication() {
        vm.getFromServer = false;
        vm.promises = [];
        SomethingRepo.get().then(function(application) {
            vm.getFromServer = true;
            vm.application = application;
            vm.promises.push(Something.getCompany().then(function(company) {
                vm.company = company;
                if (vm.company.structure === ‘more_25’) {
                    return SomethingRepo.getAllOwners().then(function(owners) {
                        vm.owners = owners;
                        for(var i = 0; i < vm.owners.length; i++) {
                            vm.promises.push(getOwnerFiles(vm.owners[i]));
                        }
                    }
                }
            }
            vm.promises.push(SomethingRepo.getSomethingOne().then(function(somethingOne) {
                vm.somethingOne = somethingOne;
            }
            vm.promises.push(SomethingRepo.getSomethingTwo().then(function(somethingTwo) {
                vm.somethingTwo = somethingTwo;
            }
            vm.promises.push(SomethingRepo.getSomethingThree().then(function(somethingThree) {
                vm.somethingThree = somethingThree;
            }
            /* and a few more like the above */
            $q.all(vm.promises).then(function(){
                postGet();
            }).finally(function() {
                vm.promises = [];
            });
        }
    }

    function postGet() {
        /* does something with the data acquired from SomethingRepo */
    }

    /* when an application is send */
    function send() {
        somethingApplication.promises = [];
        somethingApplication.errors = [];
        if (vm.getFromServer) {
            update();
        } else { 
            create();
        }
    }

    function update() {
        somethingApplication.promises.push(SomethingRepo.update(vm.application).then(angular.noop, function(error) {
            somethingApplication.parseErrors(error, ‘Some error’);
        }));
        patchInfo();
    }

    function create() {

    }

    function patchInfo() {
        somethingApplication.promises.push(SomethingRepo.patchAccount(vm.account).then(angular.noop, function(error) {
            somethingApplication.parseErrors(error, ‘Account error: ‘);
        }
        /* a few more patches */
        $q.all(somethingApplication.promises).then(function() {
            /* display dialog */
        }, angular.noop).finally(function() {
            postGet();
            somethingApplication.promises = [];
            if (somethingApplication.errors.length >= 1) {
                vm.errors = somethingApplication.errors;
            }
        });
    }
}

somethingApplication.service.js

function somethingApplication(SomethingRepo) {
    var promises = [], errors = [];

    var service = {
        promises: promises;
        errors = errors;
        parseErrors: parseErrors;
    };

    return service; 


    function parseErrors(error, base_string) {
        angular.forEach(error.data.erros, function(value_params, key_params) {
            this.errors.push(base_string + ‘ ‘ + key_params.replace(/_/g, ‘ ‘) + ‘ ‘ + value_params);
        }, this);
    }
}

somethingRepo.js

function SomethingRepo(Server) {
    function get() {
        return Server.get(‘/something/application’, null, {noGlobal: true});
    }
}

我减少了文件,但它们包含更多这样的代码。 控制器的重点是为另一个网站创建或更新应用程序。在我的网站上,我有一个与其他网站上的表格相对应的字段形式。如果您已经提交了申请,但想对其进行更新,则已经提交的信息将从另一个网站加载。

问题是,为了创建或更新应用程序,向其请求了许多不同的端点。

在AngularJS中,我存储来自每个请求的承诺,并最终异步运行它们。在TypeScript和Angular中,我想使用Observables并订阅数据更改。

我如何开始?如何从另一个Observable订阅一个Observable的require参数?任何建议如何进行?

1 个答案:

答案 0 :(得分:2)

下面是一个示例,演示如何在场景中轻松使用可观察对象-

您的服务将是这样-

import { Injectable } from '@angular/core';
import { AppConstants } from '../../app.constants';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ExampleService {
    constructor(private appconstants: AppConstants, private http: HttpClient) { }

    get() {
        return this.http.get(this.appconstants.apiUrl);
    }

    getSomethingOne() {
        return this.http.get(this.appconstants.apiUrl1);
    }

    getSomethingTwo() {
        return this.http.get(this.appconstants.apiUrl2);
    }
}

然后只需按如下所示在组件中使用它即可-

import { Component } from '@angular/core';
import { forkJoin } from 'rxjs';
import { ExampleService } from '../services/example.service';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent {

    data;
    dataOne;
    dataTwo;

    constructor(private exampleService: ExampleService) { }

    getApplication() {
        const combined = forkJoin([
            this.exampleService.get(),
            this.exampleService.getSomethingOne(),
            this.exampleService.getSomethingTwo()
        ]);
        combined.subscribe(res => {
            this.data = res[0];
            this.dataOne = res[1];
            this.dataTwo = res[2];
        });
    }
}
相关问题