javascript 异步等待反应。 setState 不等待
javascript async await with react. setState doesn't wait forawait
我正在构建一个组件来获取组的成员,然后从 api 下载图像。它在 componentDidMount 中使用异步等待,照片可以正确返回。但是即使我正在使用异步等待。它不会等待图像解析。因此在 setState 中它将 return 一个承诺。
我的组件:
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
导出默认的 TeamCardPersonaMembers;
任何帮助或指点将不胜感激!干杯!
map
的标准实现不等待传递给它的回调。导致 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
}
编辑:
请注意,上述方法按顺序执行承诺。正如 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);
}))
但如果请求过多,此方法可能会使您的网络过载,请谨慎使用。
await
关键字仅适用于其他异步函数,或 return 和 Promise
的函数。所以我认为像你一样在 members.map
上 await
没有意义。那只是一个普通的同步函数调用。您需要将其设置为:
我正在构建一个组件来获取组的成员,然后从 api 下载图像。它在 componentDidMount 中使用异步等待,照片可以正确返回。但是即使我正在使用异步等待。它不会等待图像解析。因此在 setState 中它将 return 一个承诺。
我的组件:
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
导出默认的 TeamCardPersonaMembers;
任何帮助或指点将不胜感激!干杯!
map
的标准实现不等待传递给它的回调。导致 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
}
编辑: 请注意,上述方法按顺序执行承诺。正如 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);
}))
但如果请求过多,此方法可能会使您的网络过载,请谨慎使用。
await
关键字仅适用于其他异步函数,或 return 和 Promise
的函数。所以我认为像你一样在 members.map
上 await
没有意义。那只是一个普通的同步函数调用。您需要将其设置为: