useEffect 等待异步函数的结果

Posted

技术标签:

【中文标题】useEffect 等待异步函数的结果【英文标题】:useEffect wait for a result from the async function 【发布时间】:2020-04-08 21:10:02 【问题描述】:

我正在尝试在 React 应用程序中为 POST 请求创建一个函数(由于我在几个地方需要它),它应该在 useEffect 语句中返回一个 responseText。我用谷歌搜索的变体不是异步的 - 在从服务器获取响应之前将字符串 console.log("JSON", json) 放入控制台 JSON undefined ...

useEffect(() => 
        (async function() 
            try 
                const response = await post_return(postData);
                const json = await JSON.stringify(response);
                console.log("json", json);
             catch (e) 
                console.error(e);
            
        )();
    , [postData]);
const API_URL_REGISTRATION = "https:.....";

export function post_return (dataPost)  
    var xhr = new XMLHttpRequest();
    xhr.open("POST", API_URL_REGISTRATION, true);

    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.onreadystatechange = function () 
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) 
            console.log("xhr.status", this.status);
            console.log("this.responseText", this.responseText);
            return  xhr.status
        
    ;
    xhr.onload = function () 
        console.log("xhr.status", this.status);
        console.log("this.responseText", this.responseText);
        return  xhr.status;
    ;

    xhr.onerror = function () 
        alert('Error' + this.status);
    ;
    xhr.send(JSON.stringify(dataPost));


也试过了:

导出异步函数 post_return (dataPost) ...

和:

xhr.onreadystatechange = 异步函数 ()

我做错了什么? 谢谢,

【问题讨论】:

是否必须使用 xmlhttprequest,是否可以使用内置 fetch ? 你可以参考这里,如果可以的话请告诉我codesandbox.io/s/59356038-so-2kxd7 【参考方案1】:

post_return 函数的第一个问题是它立即返回undefined,因此response 变量值实际上是undefined,并且使用undefined 调用JSON.stringify 的结果也是undefined .您应该做的是更正post_return,使其返回Promise

最简单的解决方案是像这样使用内置的fetch

export function async post_return (dataPost)  
  const response = await fetch(API_URL_REGISTRATION, 
    method: 'POST',
    body: JSON.stringify(dataPost),
    headers: 
      'Content-type': 'application/x-www-form-urlencoded'
    
  );
  
  if (response.ok) 
    return response.json();
  
  
  // Here you can do some basic error parsing/handling
  throw new Error();

【讨论】:

【参考方案2】:

Rafal2228,感谢您的帖子,我根据需要采用了它

export async function post_return(url, dataPost) 
    const response = await fetch(url, 
        method: 'POST',
        body: JSON.stringify(dataPost),
        headers: 
            'Content-type': 'application/x-www-form-urlencoded'
        
    );
    const json = await response.json();
    return 
        status: response.status,
        body: json
    ;

useEffect(() => 
        (async function() 
            try 
                if (postData.email !== undefined)
                
                    const response = await post_return(API_URL_REGISTRATION, postData);
                    // console.log("response", response);
                    setshowLoader(false);
                    if (response.status === 200) 
                        navigate("/login")
                     else alert(response.body);
                
             catch (e) 
                console.error('Ошибка ' , e);
            
        )();
    , [postData]);

【讨论】:

以上是关于useEffect 等待异步函数的结果的主要内容,如果未能解决你的问题,请参考以下文章

异步等待不等待 useEffect 内的响应

如何取消firebase的useEffect订阅

如何在 React 的 UseEffect() 中调用异步函数?

在 useEffect 挂钩中取消所有异步/等待任务以防止反应中的内存泄漏的正确方法是啥?

在 useEffect 挂钩中进行的异步调用的测试结果

在反应中使用异步等待从firebase存储中检索图像