javascript async ждут с реакцией. setState не ждет forawait - PullRequest
0 голосов
/ 06 июня 2019

Я создаю компонент, чтобы получить членов группы, а затем загрузить изображение из API.Он использует асинхронное ожидание в componentDidMount, и фотографии возвращаются правильно.однако, хотя я использую асинхронное ожидание.он не ждет разрешения изображений.Таким образом, в setState он вернет обещание.

мой компонент:

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;
}

}

console.log

enter image description here

экспорт по умолчанию TeamCardPersonaMembers;

любая помощь или указатели будут с благодарностью!Ура!

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Стандартная реализация map не ожидает обратного вызова, переданного ей. В результате вызов карты возвращает обещания до завершения обратных вызовов. У вас есть два варианта.

    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
}

Edit: Обратите внимание, что вышеуказанный метод выполняет обещания в последовательности. Как указывает Джед, если вы хотите запустить все запросы одновременно и дождаться их разрешения,

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);
}))

Но этот метод может перегрузить вашу сеть, если запросов слишком много, используйте с осторожностью.

0 голосов
/ 06 июня 2019

Ключевое слово await работает только с другими асинхронными функциями или функциями, которые возвращают Promise.Поэтому я не думаю, что имеет смысл await на members.map, как вы.Это просто обычный вызов функции синхронизации.Вам нужно настроить его как:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...