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

Posted

技术标签:

【中文标题】如何结合这两个功能,让一个等到它完成,然后运行另一个【英文标题】:How to combine these two functions so one waits until it's finished and then runs the other 【发布时间】:2022-01-13 21:34:52 【问题描述】:

有问题的两个函数:

   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 并将其保存到一个变量中,然后在创建歌曲时处理提交并将变量添加到我的数据库中。我不确定它是否很小,或者我是否完全错过了一个概念。我应该返回 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;

【问题讨论】:

【参考方案1】:

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

即:

&lt;form onSubmit=handleSubmit&gt;

&lt;button onClick=uploadSong type="submit"&gt;Submit&lt;/button&gt;

这样做的影响是会触发两个动作。

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

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

【讨论】:

是的,我提交了handleSubmit 函数,并且在得到帖子的响应后不得不进行调度。感谢您的帮助!

以上是关于如何结合这两个功能,让一个等到它完成,然后运行另一个的主要内容,如果未能解决你的问题,请参考以下文章

如何让 android 应用程序等到电话完成?

如何让phantomJS webdriver等到加载特定的HTML元素然后返回page.source?

如何让它等到用户输入日期然后关闭对话框并将值写入其目的地?

Node.js 等到异步函数完成,然后继续执行其余代码

Node.js 等到异步函数完成,然后继续执行其余代码

如何让一个方法等到另一个方法完成它在Objective C中工作?