开发者问题收集

在 React 中使用 async 和 await 依次执行函数

2020-09-23
7054
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;

在上面的代码中,单击按钮时,我将调用 uploadData 函数。在 uploadData 函数中,uploadPhoto 函数应首先执行,然后将 URL 设置为 setPhotoUrl 钩子。在存储图像并获取 URL 后,addItems 函数应执行,并将照片的标题和 URL 发布到 Express 服务器。但情况并非如预期。

2个回答

您可以将 addItems 方法的调用包装在 useEffect 中,并仅在设置了 photoUrltitle 时才有条件地触发它。

useEffect(()=>{
 if(title && photoUrl)
 addItems();
},[title,photoUrl])

此后,您应该将 titlephotoUrl 重新设置为空字符串或 null。因此,在您的 addItems 方法中添加以下行

 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);
  };
Siddhant Varma
2020-09-23

您必须将您的函数转换为 async 函数,以便能够 await 它们。因此,请改为

const uploadPhoto = () => {const addItems = () => {

const uploadPhoto = async () => { 和此 const addItems = async() => {

然后将您的 uploadData 函数更改为:

  const uploadData = async () => {
    await uploadPhoto();
    await addItems();
  };
Gh05d
2020-09-23