Javascript 使用async执行一个又一个函数,并在react中等待 const AddNew=(道具)=>{ const[photoUrl,setPhotoUrl]=useState([]); const[title,setTitle]=useState(); const[photos,setPhotos]=useState([]); useffect(()=>{ axios.get(“http://localhost:80/newItem)然后((res)=>{ console.log(res.data); }); }); 常量上传照片=()=>{ 控制台日志(“一”); 常量存储=fire.storage(); const reference=storage.ref(); 照片。forEach((照片)=>{ 参考 .孩子(照片.姓名) .put(照片) .那么( (快照)=>{ snapShot.ref.getDownloadURL()。然后((url)=>{ console.log(url); setPhotoUrl((photoUrl)=>[…photoUrl,url]); }); }, (错误)=>{ 控制台日志(err); } ); }); }; 常量附加项=()=>{ 控制台日志(“两个”); const photo=photoUrl; const uploadData=axios .post(“http://localhost:80/newItem", { 照片:照片,, 标题:标题,, }) 。然后((res)=>警报(res)) .捕获((e)=>警报(e)); window.location.reload(false); }; const uploadData=async()=>{ 等待上传照片; 等待补充; }; 返回( 添加新产品 { if(Array.from(e.target.files).length 标题 setTitle(e.target.value)} /> 提交 ); }; 导出默认的AddNew;
在上面点击按钮的代码中,我将进入uploadData函数。在uploadData函数中,uploadPhoto函数应首先执行,然后将URL设置为setPhotoUrl钩子。存储图像并获取URL后,addItems函数应在将照片的标题和URL发布到express服务器的位置执行但是它并没有像预期的那样发生。您可以将Javascript 使用async执行一个又一个函数,并在react中等待 const AddNew=(道具)=>{ const[photoUrl,setPhotoUrl]=useState([]); const[title,setTitle]=useState(); const[photos,setPhotos]=useState([]); useffect(()=>{ axios.get(“http://localhost:80/newItem)然后((res)=>{ console.log(res.data); }); }); 常量上传照片=()=>{ 控制台日志(“一”); 常量存储=fire.storage(); const reference=storage.ref(); 照片。forEach((照片)=>{ 参考 .孩子(照片.姓名) .put(照片) .那么( (快照)=>{ snapShot.ref.getDownloadURL()。然后((url)=>{ console.log(url); setPhotoUrl((photoUrl)=>[…photoUrl,url]); }); }, (错误)=>{ 控制台日志(err); } ); }); }; 常量附加项=()=>{ 控制台日志(“两个”); const photo=photoUrl; const uploadData=axios .post(“http://localhost:80/newItem", { 照片:照片,, 标题:标题,, }) 。然后((res)=>警报(res)) .捕获((e)=>警报(e)); window.location.reload(false); }; const uploadData=async()=>{ 等待上传照片; 等待补充; }; 返回( 添加新产品 { if(Array.from(e.target.files).length 标题 setTitle(e.target.value)} /> 提交 ); }; 导出默认的AddNew;,javascript,reactjs,ecmascript-6,async-await,Javascript,Reactjs,Ecmascript 6,Async Await,在上面点击按钮的代码中,我将进入uploadData函数。在uploadData函数中,uploadPhoto函数应首先执行,然后将URL设置为setPhotoUrl钩子。存储图像并获取URL后,addItems函数应在将照片的标题和URL发布到express服务器的位置执行但是它并没有像预期的那样发生。您可以将addItems方法的调用封装在useffect中,并且只有在设置了photoUrl和title的情况下才有条件地触发它 const AddNew = (props) => {
addItems
方法的调用封装在useffect
中,并且只有在设置了photoUrl
和title
的情况下才有条件地触发它
const AddNew = (props) => {
const [photoUrl, setPhotoUrl] = useState([]);
const [title, setTitle] = useState();
const [photos, setPhotos] = useState([]);
useEffect(() => {
axios.get("http://localhost:80/newItem").then((res) => {
console.log(res.data);
});
});
const uploadPhoto = () => {
console.log("one");
const storage = fire.storage();
const reference = storage.ref();
photos.forEach((photo) => {
reference
.child(photo.name)
.put(photo)
.then(
(snapShot) => {
snapShot.ref.getDownloadURL().then((url) => {
console.log(url);
setPhotoUrl((photoUrl) => [...photoUrl, url]);
});
},
(err) => {
console.log(err);
}
);
});
};
const addItems = () => {
console.log("two");
const photo = photoUrl;
const uploadData = axios
.post("http://localhost:80/newItem", {
photos: photo,
title: title,
})
.then((res) => alert(res))
.catch((e) => alert(e));
window.location.reload(false);
};
const uploadData = async () => {
await uploadPhoto;
await addItems;
};
return (
<div>
<Container>
<h4
className="text-center mb-5 mt-5"
style={{ borderBottom: "1px solid black" }}
>
Add a new Product
</h4>
<div style={{ width: "75%", margin: "0 auto" }}>
<Row className="text-center">
<Col sm={12} lg={12} md={12}>
<Form.Group>
<Form.File
label="upload upto 5 images"
multiple
onChange={(e) => {
if (Array.from(e.target.files).length <= 4) {
const img = Array.from(e.target.files);
setPhotos(img);
} else {
alert("You can select maximum 5 Images");
e.target.value = null;
}
}}
accept=".jpg"
/>
</Form.Group>
<Form.Group controlId="exampleForm.ControlInput1">
<Form.Label>Title</Form.Label>
<Form.Control
type="text"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</Form.Group>
<Button variant="outline-primary" onClick={uploadData}>
Submit
</Button>
</Col>
</Row>
</div>
</Container>
</div>
);
};
export default AddNew;
在此之后,您应该将标题
和照片URL
设置回空字符串或null
useEffect(()=>{
if(title && photoUrl)
addItems();
},[title,photoUrl])
您必须将函数转换为
async
函数才能等待它们。因此,请不要使用
const uploadPhoto=()=>{
和const addItems=()=>{
这个
const uploadPhoto=async()=>{
和这个const addItems=async()=>{
然后将uploadData
功能更改为:
const addItems = () => {
console.log("two");
const photo = photoUrl;
const uploadData = axios
.post("http://localhost:80/newItem", {
photos: photo,
title: title,
})
.then((res) =>{
alert(JSON.stringify(res))
setPhotoUrl('');
setTitle('');
})
.catch((e) => alert(e));
window.location.reload(false);
};
您的uploadPhoto
和addItems
方法不返回a,因此它没有什么可等待的。我猜您还必须将'photos.forEach'方法从承诺链转换为异步函数。@Gh05d如何做到这一点,先生?因为我是一名年轻的开发人员,我不适合这样做……您能用这段代码向我解释一切吗上面的代码?先生,点击提交按钮,它应该一个接一个地执行函数,然后你应该返回两个函数的承诺,这样你就可以链接你的方法。先生,怎么做?你能用上面的代码解释我吗?我做了,但在点击提交按钮之前,只有图像被上传,你正在设置状态它本身是一个异步操作。即使您确实从第一个函数返回了一个承诺,但在运行第二个函数时,setState
可能尚未调用,并且此时您的状态可能为空。跟踪它的唯一方法是使用useffect
。这种方法确保您仅在具有ate变量集,您需要将其发送回服务器。先生,我喜欢这样做,但图像将在函数完成后上载
const uploadData = async () => {
await uploadPhoto();
await addItems();
};