【问题标题】:javascript async await with react. setState doesn't wait forawaitjavascript 异步等待反应。 setState 不等待
【发布时间】:2019-10-21 18:30:39
【问题描述】:

我正在构建一个组件,用于获取组成员,然后从 api 下载图像。它在 componentDidMount 中使用异步等待,并且照片正确返回。但是,即使我使用的是异步等待。它不会等待图像解析。因此在 setState 中它会返回一个 Promise。

我的组件:

import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUser } from "@fortawesome/free-solid-svg-icons";
import {
    GetGroupMembers,
    getImage
} from "../../../HttpRepositories/oneApiRepository";

class TeamCardPersonaMembers extends React.Component {
    constructor(props) {
        super(props);
        this._isMounted = false;
    }

state = {
    members: []
};

async componentDidMount() {
    this._isMounted = true;
    let members = await GetGroupMembers(this.props.teamId);

    const membersToSend = await members.map(async member => {
        const memberPhotoUrl = `${process.env.REACT_APP_ONE_API_URL}/api/users/${
            member.id
        }/photo`;

        let memberPhoto = await getImage(memberPhotoUrl);
        member.photo = memberPhoto;
        return member;
    });

    if (this.state.member !== "error" && this._isMounted) {
        this.setState({ members: membersToSend });
    }
}

render() {
    let members = [];

    console.log(this.state);

    if (this.state.members.length > 0) {
        this.state.members.map(member => {
            console.log("this is the member ", member);
            const memberImg = (
                <img
                    key={member.id}
                    src={member.photo}
                    alt={member.displayName}
                    className="team-card-persona-wrapper"
                    title={member.displayName}
                />
            );

            members.push(memberImg);
        });
    }

    return <React.Fragment>{members}</React.Fragment>;
}

componentWillUnmount() {
    this._isMounted = false;
}

}

控制台日志

导出默认 TeamCardPersonaMembers;

任何帮助或指点将不胜感激!干杯!

【问题讨论】:

    标签: reactjs async-await ecmascript-2016


    【解决方案1】:

    map 的标准实现不等待传递给它的回调。导致 map 调用在回调完成之前返回 Promise。你有两个选择。

        const membersToSend = []
        for (const member of members) {
            const memberPhotoUrl = `${process.env.REACT_APP_ONE_API_URL}/api/users/${
                member.id
            }/photo`;
    
            let memberPhoto = await getImage(memberPhotoUrl);
            member.photo = memberPhoto;
            membersToSend.push(member);
        }
    
    

    或滚动您自己的异步映射实现。

    Array.prototype.mapAsync = async function (callback) {
      const output = []
      for (const el of this)
        output.push( await callback(el) ) <-- // Note the await on the callback
    
      return output
    }
    
    

    编辑: 请注意,上述方法按顺序执行承诺。正如 Jed 指出的那样,如果您想一次触发所有请求并等待它们解决,

    const memberPhotos = await Promise.all(members.map(member => {
       const memberPhotoUrl = `${process.env.REACT_APP_ONE_API_URL}/api/users/${
                member.id
            }/photo`;
    
            return getImage(memberPhotoUrl);
    }))
    

    但如果请求过多,此方法可能会使您的网络过载,请谨慎使用。

    【讨论】:

    • 我选择了 for 循环。谢谢您的帮助。想我应该检查 MDN 的异步支持。干杯。可能时会接受作为答案
    【解决方案2】:

    await 关键字仅适用于其他异步函数,或返回 Promise 的函数。所以我认为像你一样在members.mapawait 是没有意义的。这只是一个正常的同步函数调用。您需要将其设置得更像:

    https://flaviocopes.com/javascript-async-await-array-map/

    【讨论】:

      猜你喜欢
      • 2019-05-10
      • 1970-01-01
      • 2016-07-07
      • 2016-03-25
      • 2017-10-09
      • 2020-11-23
      • 2018-08-19
      相关资源
      最近更新 更多