useState 与异步函数返回 Promise <pending>

Posted

技术标签:

【中文标题】useState 与异步函数返回 Promise <pending>【英文标题】:useState with async function returning Promise <pending>useState 与异步函数返回 Promise <pending> 【发布时间】:2020-06-08 01:25:45 【问题描述】:

所以,我知道这个问题已经被问了 100 次了,但在我的例子中似乎没有一个解决方案有效。

我正在使用useState 挂钩将状态更新为值initialValues,该值从getInitialValues 函数返回数据

const [initialValues, setInitialValues] = useState(getInitialValues());

getInitialValues 函数进行逻辑检查并返回一个对象或另一个函数retrieveDetails()

const getInitialValues = () => 
   let details;
   if(!addressDetails) 
      details = retrieveDetails();
    else 
      details =  
         ...,
         ...,
         ...
      ;
   
   return details;

函数retrieveDetails 是一个异步函数,它进行 API 调用,我等待响应并返回从响应中接收到的对象。

const retrieveDetails = async () => 
   const addr = addressDetails[currentAddress];
   const  addressLookup  = addr;
   const key = process.env.API_KEY;
   const query = `?Key=$key&Id=$addressLookup`;
   const addrDetails = await new AddrService().getAddressDetails(query);
   return addrDetails;

但是,当我记录状态 initialValues 时,它会返回 Promise &lt;pending&gt;?

即使移除 API 调用并简单地返回一个对象,也会呈现相同的结果。

不确定实际返回对象的最佳解决方法?

任何帮助将不胜感激。

【问题讨论】:

您可以使用Suspense 来解决这个问题。请参阅 traditional approaches 了解没有它该怎么办。 "getInitialValues 函数进行逻辑检查,然后返回一个对象或另一个函数retrieveDetails()" - 不。 这能回答你的问题吗? How do I return the response from an asynchronous call? 【参考方案1】:

我认为没有办法将初始数据异步获取到useState,至少现在还没有。

React 不会等待您的数据到达,当您的异步操作排队(在事件循环端)时,该函数将继续运行直到完成。

目前的惯用方式是在一个 effect 中获取数据并更新状态。

useEffect(() => 
  getData(someParam).then(data => setState(data))
, [someParam]) 

您可以在DOCS了解更多信息

【讨论】:

...然后您会收到关于尝试在未安装组件中设置状态的开发人员控制台警告。 @SimonB。实际上,如果您在卸载时不处理取消或忽略,大多数情况下您会得到它。我写过它,你可能会发现它很有用。 debuggr.io/react-update-unmounted-component 好萨吉夫!但是使用 useReducer 加倍努力,并且在许多用例中添加单独的 useEffect 只是为了避免该警告可能会导致大量重复代码。您如何看待我下面的替代答案? :) @SimonB。好吧,这超出了这个问题的范围,我确实在我的帖子中提到了类似的解决方案,尽管我更喜欢“可中止”的 useEffect 谢谢!在 Promise.all 之后在 Dropzone 上工作,因为不需要按钮【参考方案2】:
const retrieveDetails = async () => 
   const addr = addressDetails[currentAddress];
   const  addressLookup  = addr;
   const key = process.env.API_KEY;
   const query = `?Key=$key&Id=$addressLookup`;
   const addrDetails = await Promise.resolve(new AddrService().getAddressDetails(query))
   return addrDetails;



**try this once changed the function a bit**

【讨论】:

现在将initialValues 状态设置为Promise &lt;resolved&gt;: … 编辑检查一次,将 async 和 await 放入函数中 根据定义,它不会仍然是一个承诺 不幸的是,仍然收到Promise &lt;pending&gt;:/ @warmachine 仅供参考,async 和 await 只是 Promise 的糖。一旦你有了async 关键字,你的函数就会返回一个promise,你无法改变它。 await 关键字是 Promise 解析和生成器 yield 的包装器。

以上是关于useState 与异步函数返回 Promise <pending>的主要内容,如果未能解决你的问题,请参考以下文章

在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]

错误:类型不是 ES5/ES3 中的有效异步函数返回类型,因为它没有引用与 Promise 兼容的构造函数

async与await异步编程

当异步函数不应该返回 Promise 时,为啥我需要等待它?

js-20170830-Promise对象

Promise对象解读