如何使用 Promise 填充对象?

Posted

技术标签:

【中文标题】如何使用 Promise 填充对象?【英文标题】:How can i use promises to populate object? 【发布时间】:2018-04-06 05:57:25 【问题描述】:

我有一个小问题.. 我依赖于 2 个服务,我循环所有组织,对于每个组织,我循环连接到组织的系统,将每个系统推送到一个对象。这很好用,在这里没问题......当我创建我的地图时出现问题,因为此时,this.systemList 对象是空的......所以我只希望在我完成后调用我的 createMap() 函数将所有项目添加到数组(this.systemList)

所以我想以某种方式检查是否所有组织和所有系统都完成了循环,并且所有系统都已添加到:this.systemList 数组,首先在这里调用this.createMap()

希望它有意义吗?

在此处查看代码:

methods: 
    getSystemsForOrganization(orgId) 
        SystemService.getSystemsForOrganization(orgId).then((response) => 
            let systems = response.data.systems;
            let systemPromises = [];
            if(systems) 
                systems.forEach((system, index, array) => 
                    let systemHasAlarms = !!system.pending_events;

                    let systemObject = 
                        id: system.id,
                        name: system.name,
                        latitude: system.latitude,
                        longitude: system.longitude,
                        latlng: [system.latitude, system.longitude],
                        has_alarms: systemHasAlarms
                    ;
                    this.systemList.push(systemObject);
                );
            
        );
    ,
    getCurrentOrganizations() 
        OrganizationService.getOrganizationData().then((response) => 
            let organizations = response.data.organizations;

            let organizationsIds = organizations.map((org) => 
                return org.id;
            );

            organizationsIds.forEach((id, index, array) => 
                this.getSystemsForOrganization(id);
            );
        );

    ,
,
mounted() 
    this.getCurrentOrganizations();
    this.createMap();

【问题讨论】:

【参考方案1】:

代码中的 cmets 应该是不言自明的

您的主要问题是没有返回等待的承诺

methods: 
    getSystemsForOrganization(orgId) 
        // added "return" to return the promise so you can wait on it
        return SystemService.getSystemsForOrganization(orgId).then((response) => 
            let systems = response.data.systems;
            let systemPromises = [];
            if(systems) 
                systems.forEach((system, index, array) => 
                    let systemHasAlarms = !!system.pending_events;

                    let systemObject = 
                        id: system.id,
                        name: system.name,
                        latitude: system.latitude,
                        longitude: system.longitude,
                        latlng: [system.latitude, system.longitude],
                        has_alarms: systemHasAlarms
                    ;
                    this.systemList.push(systemObject);
                );
            
        );
    ,
    getCurrentOrganizations() 
        // return the promise
        return OrganizationService.getOrganizationData().then((response) => 
            let organizations = response.data.organizations;

            let organizationsIds = organizations.map((org) => 
                return org.id;
            );
            // instead of organizationsIds.forEach, use organizationsIds.map, so we
            // have an array of promises for Promise.all to wait on
            let promises = organizationsIds.map(id => 
                return this.getSystemsForOrganization(id);
            );
            // returns a Promise that "waits" for all promises to resolve
            return Promise.all(promises);
        );

    ,
,
mounted() 
    this.getCurrentOrganizations().then(() => 
        this.createMap();
    );

代码也可以“简化”为

methods: 
    getSystemsForOrganization(orgId) 
        // added "return" to return the promise so you can wait on it
        return SystemService.getSystemsForOrganization(orgId).then((data) => 
            this.systemList.push(
                ...(data.systems||[])
                .map((id, name, latitude, longitude, pending_events)=> (
                    id,
                    name,
                    latitude,
                    longitude,
                    latlng: [latitude, longitude],
                    has_alarms: !!pending_events
                ))
            )
        );
    ,
    getCurrentOrganizations() 
        return OrganizationService.getOrganizationData()
        .then(response => 
            Promise.all(response.data.organizations
                .map((id) => this.getSystemsForOrganization(id))
            )
        );
    ,
,
mounted() 
    this.getCurrentOrganizations().then(this.createMap);

【讨论】:

以上是关于如何使用 Promise 填充对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Promise填充层次结构,其中每个级别都需要满足之前的级别?

Promise 的 .then 和 .catch 是如何工作的?

如何获取promise对象的值

如何获取promise对象的值

如何获取promise对象的值

如何正确处理 Promise.all:未定义