首页 > 解决方案 > 遍历数组 - 将 promise 返回的值添加到数组中的每个对象

问题描述

基本上,我有一个小小的困惑。我有一组对象,每个对象都有一个人的名字和这个人居住的城市。

现在,我想要做的是遍历整个数组并获取循环中每个项目的城市距离,比如加利福尼亚。

我想要做的是使用城市名称来获取该城市与加利福尼亚州的距离,并将其添加到数组中的每个对象中。

所以,假设索引 1 的项目有阿拉巴马州,那么我想要从阿拉巴马州到加利福尼亚州的距离,以及到该项目的财产距离

比如 {name: John1, city:'Alabama', distance:'不管距离是多少'}

现在,我已经使用 promise.allsettled 完成了该操作,但不确定它返回数据的顺序是否相同或混淆,因此不确定我是否将正确的距离附加到正确的项目。

我希望它以正确的顺序返回东西,并且我所做的方式是正确的,但是如果有更好和更清洁的方式来做到这一点,那么我想知道如何做到这一点。

这里也是代码

import React from 'react';
import _ from 'lodash';
import axios from 'axios';

export default class GetDistance extends React.Component{
    state = {
        loggedInCity: 'Georgia',
        isLoading: false,
        projectsWithDistance:[],
        projects : [
            {
                name: 'John1',
                city: 'Alabama'
            },
            {
                name: 'John2',
                city: 'Arizona'
            },
            {
                name: 'John3',
                city: 'California'
            }, 
            {
                name: 'John4',
                city: 'Colorado'
            },
            {
                name: 'John5',
                city: 'Connecticut'
            },
            {
                name: 'John',
                city: 'Florida'
            },
            {
                name: 'John6',
                city: 'Idaho'
            },
            {
                name: 'John7',
                city: 'Kansas'
            },
            {
                name: 'John8',
                city: 'Maine'
            },
            {
                name: 'John9',
                city: 'Hawaii'
            },
            
        ]
    }

    getDistance = (zipFrom, zipTo) => {   
        console.log('zipFrom : ',zipFrom);
        console.log('zipTo : ',zipTo);
        return new Promise((resolve, reject)=>{
          axios.post('http://localhost:8080/getDistance',{
          zipcodeTo:zipTo,
          zipcodeFrom:zipFrom
        })
        .then((res)=>{
          console.log('res from get distance in reducer : ',res.data);
          resolve(res.data.distance);
        })
        .catch((err)=>{
          console.log('error from distance : ',err)
          reject('');
        });
        })
        
    }

    async componentDidMount(){
        const projects = this.state.projects;
        const from = this.state.loggedInCity;
        const promisesArr = [];
        for(var i=0; i<projects.length;i++){
            let distance = 0;
            let to = projects[i].city;
            distance = this.getDistance(from,to);
            promisesArr.push(distance);
        }
        const results = await Promise.allSettled(promisesArr);
        console.log('results : ',results);
        const projectsWithDistance = [];
        for(var i=0; i<projects.length;i++){
            let newProject = _.cloneDeep(projects[i]);
            const distanceFromResult = results[i].value;
            newProject.distance = distanceFromResult;
            projectsWithDistance.push(newProject);
        }
        this.setState({
            isLoading:false,
            projectsWithDistance
        });
    }

    render(){
        const {projectsWithDistance,isLoading, loggedInCity} = this.state;
        return(
            <div>
                {isLoading?<h1>'Loading...</h1>:''}
                {!isLoading && projectsWithDistance.length>0?projectsWithDistance.map((item)=>{
                    return <div>Distance between {loggedInCity} and {item.city} is {item.distance}</div>
                }):''}
            </div>
        )
    }
}

标签: javascriptreactjsloopspromise

解决方案


for您可以逐个循环替换for..of

const results = []
for await (const project of projects){
  let distance = 0;
  let to = projects[i].city;
  this.getDistance(from,to).then(distance => results.push(distance))
}

for of循环本质上是异步的。所以这应该完成它。


推荐阅读