【问题标题】:POST not finishing before .then() runs in async callPOST 未在 .then() 在异步调用中运行之前完成
【发布时间】:2020-09-02 03:56:09
【问题描述】:

我正在发出一个大约需要 10 秒才能完成的 POST 请求...但我的警报会在单击时立即显示,然后服务器返回 200。为什么?以及如何修复它以等待服务器完成操作?

const handleClick = async () => {
    const response = await fetch("/create", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(highlights),
    }).then(alert("hi!"));
};

如果我将 .then 更改为 .then(() => {alert("hi!");}) 如下所示,在发出服务器请求时页面会闪烁/似乎刷新但警报根本不显示

更新:

如果我使用此代码:

const handleClick = async () => {
    try {
        const response = await fetch("/create", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(highlights),
        });
        alert("first");
    } catch (error) {}
    alert("second");
};

第二个警报在按钮被按下时立即触发,第一个警报永远不会触发。

【问题讨论】:

    标签: javascript reactjs flask async-await fetch


    【解决方案1】:

    引入 Async/await 是为了克服 then/catch 链接问题。你不需要使用 then ,你必须使用 try/catch。 async/await 总是与 try/catch 一起使用。

    
    const handleClick = async () => {
    try{
        const response = await fetch("/create", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(highlights),
        })
    alert("hi!")
    }
    catch(error){}
    }
    

    当您使用 try/catch 时,直到 i/o 调用完成,控制才会进一步。因此,您也可以将警报或任何代码放在 try catch 块之外。一旦等待调用完成,它将被执行。 像这样

    
    try{
        const response = await fetch("/create", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(highlights),
        })
    
    }
    catch(error){}
    }
    alert("hi!")
    

    试试这个。

    如果您使用的是 reactjs 和 nodejs,那么我已经模拟了您的要求并且它按预期工作。 我用过 reactjs 钩子。 一旦调用成功,就会触发警报。

    你可以看看这个。 https://github.com/ajaysikdar/reactjs-nodejs-alert

    【讨论】:

    • 感谢您的回答,但这实际上与我的理解不符。因为 Async 函数总是返回一个 Promise(它只是对 Promise 的语法糖),并且 .then() 和 .catch() 工作得很好。 (您的解决方案也不会改变行为)
    • @Lumen async 和 await 是 Promise 链的 替换。你需要等待承诺。不要使用then。你说 await 是语法糖,但如果你还要使用then,那语法糖是什么?
    • @JMadelaine 明白了。但是,这仍然不能解决我的核心问题。有任何想法吗?要明确我的问题:如果我只是“等待”,服务器请求会运行,之后什么都不会运行(在这种情况下是警报)。
    • 你确定你已经正确实现了吗?这个答案对我来说是正确的。警报必须在 async 函数内部,并且在 await 之后。
    • 你是如何触发这个函数的?如果是表单的提交按钮,请确保您使用的是e.preventDefault()
    【解决方案2】:

    试试:

    .then(() => { alert("hi"); });
    

    then 函数希望您向它传递一个函数,但您实际上是在调用一个函数 (alert),并将该函数的返回值传递给 then

    【讨论】:

    • 没有骰子。在这种情况下,我什至没有收到警报。页面在服务器操作完成之前闪烁,几乎看起来像是重新渲染。
    • @Lumen 听起来这是在表单中,您并没有阻止默认提交
    • @charlietfl 它不在表单内,但无论如何我都没有处理默认提交。这适用于这种情况吗?
    猜你喜欢
    • 2016-05-13
    • 2019-02-22
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多