如何组合这两个功能,让一个等到它完成,然后运行另一个

How to combine these two functions so one waits until it's finished and then runs the other

有问题的两个函数:

   const handleSubmit = async (e) => {

    e.preventDefault();
    console.log(songLink)
    const newSong = {
        songName,
        songLink,
        userId
    };
    const song = await dispatch(postSong(newSong))
        .catch(async (res) => {
            const data = await res.json()
            if (data && data.errors) setErrors(data.errors)
        })
    reset();
};

const uploadSong = (files) => {
    console.log(files[0])
    const formData = new FormData()
    formData.append('file', songSelected)
    formData.append('upload_preset', 'd3gthd7l')
    Axios.post("https://api.cloudinary.com/v1_1/dyhfkvy6u/video/upload", formData).then((response) => {
        console.log(response.data.url, 'responseeee')
        setSongLink(response.data.url)
    })
}

我需要 uploadSong 函数来完成上传,这样我就可以获得 response.data.url 并将其保存到一个变量中,然后在创建歌曲时处理提交并将变量添加到我的数据库中。我不确定它是否很小,或者我是否完全缺少一个概念。我应该 return url 然后等待函数吗?

整个文件:

import { useState } from "react";
import { useDispatch } from "react-redux";

import { postSong } from "../../store/song";

import { useSelector } from "react-redux";

// import { Image, Audio } from 'cloudinary-react'


import Axios from 'axios'

const SongForm = () => {
    const dispatch = useDispatch();

    const [songName, setSongName] = useState("");
    const [songLink, setSongLink] = useState("");
    const [errors, setErrors] = useState([]);

    const [songSelected, setSongSelected] = useState("")
    const [url, setUrl] = useState('')

    const reset = () => {
        setSongName("");
        setSongLink("");
        // setAlbumName('');
        // setArtistName('')
    };
    const user = useSelector((state) => state.session.user);
    const userId = user?.id

    const handleSubmit = async (e) => {

        e.preventDefault();
        console.log(songLink)
        const newSong = {
            songName,
            songLink,
            userId
        };
        const song = await dispatch(postSong(newSong))
            .catch(async (res) => {
                const data = await res.json()
                if (data && data.errors) setErrors(data.errors)
            })
        reset();
    };

    const uploadSong = (files) => {
        console.log(files[0])
        const formData = new FormData()
        formData.append('file', songSelected)
        formData.append('upload_preset', 'd3gthd7l')
        Axios.post("https://api.cloudinary.com/v1_1/dyhfkvy6u/video/upload", formData).then((response) => {
            console.log(response.data.url, 'responseeee')
            setSongLink(response.data.url)
        })
    }


    return (
        <div className="inputBox">
            <h1>Add A Song</h1>
            <ul>
                {errors.map((error, idx) => <li className='errors' key={idx}>{error}</li>)}
            </ul>
            <form onSubmit={handleSubmit}>
                <input
                    type="text"
                    onChange={(e) => setSongName(e.target.value)}
                    value={songName}
                    placeholder="Song Name"
                    name="Song Name"
                />
                {/* <input type="text"
                    type="text"
                    onChange={(e) => setSongLink(e.target.value)}
                    value={songLink}
                /> */}
                <input
                    // type="text"
                    // onChange={(e) => setSongLink(e.target.value)}
                    type='file'
                    onChange={(e) => { setSongSelected(e.target.files[0]) }}
                    // value={songLink}
                    placeholder="Song Link"
                    name="Audio File"
                />
                <button onClick={uploadSong} type="submit">Submit</button>

                {/* <Audio cloudName='dyhfkvy6u' publicId='https://res.cloudinary.com/dyhfkvy6u/image/upload/v1639007386/x8cgeebtzdfeou4p6bhw.png' /> */}

            </form>
        </div>
    );
};

export default SongForm;

您的表单似乎有一个 onSubmit 处理程序,但您还为表单的提交按钮(带有 submit 类型的按钮)分配了一个 onClick 操作。

即:

<form onSubmit={handleSubmit}>

<button onClick={uploadSong} type="submit">Submit</button>

这会触发两个动作。

如果我是你,我会删除 onClick(在按钮上)或 onSubmit(在表单上),这样你只会发生一个动作。

然后,假设您决定将 onSubmit 保留为您要触发的操作,在该函数中我将调用您要执行的两个函数。如果第一个函数(上传)是异步的,我会在调用下一个函数之前等待它的结果。