【问题标题】:Javascript Async Await wait for two functions to completeJavascript Async Await 等待两个函数完成
【发布时间】:2020-11-14 22:01:42
【问题描述】:

我很难理解异步/等待。

我有以下代码调用:

  • submitHandler() 将表单的输入发布到 Google 表格
                const scriptURL =
                        'GOOGLE SCRIPT URL'
                const form = document.forms.emailform
                fetch(scriptURL, { method: 'POST', body: new FormData(form) })
                        .then(response => {
                                console.log('Success!', response)
                                setFormSuccess(1)
                        })
                        .catch(error => {
                                console.error('Error!', error.message)
                                setFormSuccess(2)
                        })
        } 
  • childRef.current.upload() 将文件发布到 S3...

但我需要等待这两个函数的结果,然后再调用另一个函数打开模态并传入这两个函数的结果。

有人可以帮帮我吗?

非常感谢

async function onSubmit() {
                        setTimeout(() => {
                                submitHandler()
                                childRef.current.upload()
                        }, 1000)
                }
                //I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal 
                

编辑:我必须在原始问题中提到,我已经尝试在我调用的所有函数中等待,但它们都不起作用

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

我认为您只是缺少一些“等待”语句。我也修改了超时时间。

async function onSubmit() {
                    let sleep = function (ms) {
                        return new Promise(resolve => setTimeout(resolve, ms))
                    }
                    await sleep(1000)
                    await submitHandler()
                    await childRef.current.upload()
            }
            //I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal 
            

同样在 submitHandler() 中,您没有正确使用异步等待。您正在使用 .then 方法,该方法无法与 await 轻松结合。

    async submitHandler() {
            const scriptURL = 'GOOGLE SCRIPT URL'
            const form = document.forms.emailform
            try {
                let response = await fetch(scriptURL, { method: 'POST', body: new FormData(form) })
                console.log('Success!', response)
                setFormSuccess(1)
            } catch(error) {
                console.error('Error!', error.message)
                setFormSuccess(2)
            }
    } 

如果您仍想捕获错误,则必须将 fetch 包装在 try 块中。

【讨论】:

  • 谢谢抱歉,我忘了说 await submitHandler() 给出了一个错误,await 只允许在异步函数中使用
  • 我太快了,我已经编辑了我的答案。我希望它有帮助:)
  • 感谢@kevin。提出的“等待”对这种类型的表达式没有影响
  • 在 submitHandler() 函数上。我现在已经在问题中添加了这个功能
  • 非常感谢@kevin。你能给我指导一下 fetch 块的 catch 等价物吗
【解决方案2】:

您可以使用Promise.all() 来等待多个 Promise,就像这样

const result = await Promise.all([submitHandler(), childRef.current.upload()]);

【讨论】:

  • 谢谢@riwen。虽然 Kevinkreps 的回答解决了我的问题,但我也需要这个来等待第二个函数
【解决方案3】:

第一件事是如果你想在其中await,你需要将setTimeout的回调标记为async

但是setTimeout 使用回调,因此偏离了您想要的控制流。因此,我会使用一个简单的 Promise 包装器来实现它:

const promiseSetTimeout = (cb, delay) => new Promise((resolve, reject) => {
  setTimeout(async () => {
    const ret = await cb();
    resolve(ret);
  }, delay);
});

因此您可以等待它并获得所需的控制流。

function onSubmit() {
  return promiseSetTimeout(async () => {
    await submitHandler();
    await childRef.current.upload();
  }, 1000);
}

【讨论】:

  • 谢谢@Vivick 我得到 promiseSetTimeout 没有定义
  • 您确实将我给您的实现复制到同一个文件中(或者如果它在其他地方,则将其导入)?
  • 谢谢,是的,在同一个文件中 - 我只是应付并粘贴。它还有一个错误是await对await submitHandler()的这种类型的表达式没有影响
  • 这可能是因为它没有返回一个承诺
  • 谢谢 我已经修改了问题以包含 submitHandler()。有什么想法吗?
【解决方案4】:

你的函数应该返回Promise。所以返回你的fetch()

submitHeader(){
      const scriptURL =
                    'GOOGLE SCRIPT URL'
            const form = document.forms.emailform
           return fetch(scriptURL, { method: 'POST', body: new FormData(form) })
                    .then(response => {
                            console.log('Success!', response)
                            setFormSuccess(1)
                            return response;
                    })
                    .catch(error => {
                            console.error('Error!', error.message)
                            setFormSuccess(2)
                    })
    } 

所以在你的 main 函数中你可以

async function onSubmit() {
                    setTimeout(() => {
                            const response = await submitHandler()
                            // Your response will be available here
                            console.log(response);
                            childRef.current.upload()
                    }, 1000)
            }

【讨论】:

  • 谢谢我忘了提到我已经尝试了所有功能的等待,但它们都没有工作。我现在将修改我的问题
  • 但重要的是你的函数返回等待只能与 Promise 返回一起使用。
  • 提交处理函数通过 fetch 发布到 google 脚本,然后根据 fetch 是否成功捕获更改状态并捕获。很抱歉在这件事上如此愚蠢! :-)
  • 你能显示代码sn-p吗?当您的功能没有真正的回报时,我无法为您提供帮助
  • 感谢@Filip 我已将 submitHandler() 的代码添加到原始问题中。如果您还需要什么,请告诉我
猜你喜欢
  • 2018-09-23
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多