【问题标题】:Using Aysnc/await with Props将 Async/await 与 Props 一起使用
【发布时间】:2018-10-08 23:19:13
【问题描述】:

我想使用 async 和 await 与 props。

所以基本上我有一个 onRefresh 函数,当用户向下滚动时它会刷新。

在这里,一旦我的 reducer 成功更新数据,我想将状态更改为 false

onRefresh = () => {
        this.setState({isFetching: true}, () => {
            refreshData = async () => {
            await this.props.indianCurrency()
            await this.props.exchangeToDisplay(this.coinURL, true)
            await  this.setState({isFetching: false})
            }
        })

    } 

在 await this.props.indianCurrency() 操作中,我添加了一个 console.log 语句来查看它是否正在执行。

这是我对 indianCurrency 的操作

export const indianCurrency = () => {
  console.log("inside Indian currency")
  return function (dispatch) {
    dispatch({type: CURRENCY_FETCHING})
    axios.get(CurrencyRateLinkINR).then((response) => {
      return (
        dispatch({
          type: CURRENCY_INR,
          payload: response.data
        })
      )
    }).catch((error) => {
      return (
        dispatch({
          type: CURRENCY_ERROR,
          payload: error.data
        })
      )
    })
  }
}

对于 exchangeToDisplay,我的操作看起来像这样

export const exchangeToDisplay = (exchangURL, random) => {
    console.log(random)
    console.log("on Refresh check as well")
    return function (dispatch) {
            if (random == undefined) {
               dispatch({type: EXCHANGE_CURRENCY_FETCHING })
             }
            let koinexApi = axios.get(koinex)
            let coinDeltaApi = axios.get(coinDelta)
            let multipleExchangeDataApi = axios.get(multipleExchangeData + exchangURL + "-usd") 
            Promise.all([koinexApi, coinDeltaApi , multipleExchangeDataApi]).then(function(values) {
                return(
                    dispatch({
                        type: EXCHANGE_CURRENCY_FETCH_SUCCESS,
                        payload: values
                    })
                 )   
            }).catch((error) => {
                return (
                    dispatch({
                        type: EXCHANGE_CURRENCY_FETCH_ERROR,
                        payload: error
                    })
                )
             })
    }
}

令我惊讶的是,没有什么是不登出的。所以我有理由相信我在这里没有正确使用 async/await?那么有人可以指导我如何正确使用 async 和 await 吗?

注意:我故意不粘贴 reducer code,因为我相信问题恰好出在我的 async/await 中,因为如果需要,它甚至没有运行 export const indianCurrency = () => {那么请告诉我,我会粘贴的。

【问题讨论】:

  • 你需要等待 axios.get,因为该代码也是一个承诺
  • @Gonzalo.- 你能在回答部分解释一下吗?
  • @KuchBhi 他说axios 请求是异步的,因此您也需要await 它。你正在混合.thenasync/await。坚持一种模式。要么将你的 async/await 包装成简单的 try/catch 块,要么用 .then(...).then(...).then(...) 链接你的承诺。阅读本文了解更多信息:pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html

标签: reactjs react-native


【解决方案1】:

您当前代码的问题在于您没有返回承诺。

所以如果你改变了

...
axios.get(...)

...
return axios.get(...)

那么您的顶级等待(如await this.props.indianCurrency())实际上将等待承诺。

另一种选择是使您的获取代码异步(尽管您仍然需要返回一个值):

export const indianCurrency = async () => {
  ...
  const results = await axios.get(...)
  return results
}

不用说,Promise.all(...) 也是如此——return Promise.all(...) 或使其异步/等待。

此外,正如@NoobieSatan 在 cmets 中指出的那样,您的 refreshData 代码似乎很可疑。为什么要在状态回调中定义一个函数?也许您打算在外面定义它并在里面调用它?

refreshData = async () => {
    await this.props.indianCurrency()
    await this.props.exchangeToDisplay(this.coinURL, true)
    this.setState({isFetching: false}) // you don't need await here
}

onRefresh = () => {
    this.setState({isFetching: true}, refreshData)
} 

但话又说回来,这不是您使用setState 回调的方式或原因。如果您的意图是显示加载标志,然后只是触发一些后台提取,那么您应该在 setState 之后调用 refreshData

onRefresh = () => {
    this.setState({isFetching: true})
    refreshData()
} 

一旦refreshData 完成(您仍然需要返回 async/await 的承诺才能工作),它将更新状态并且 React 将正确地重新渲染组件。而且你不需要等待 setState。

【讨论】:

  • 另外他一开始也没有调用函数refreshData
  • @Mrchief 因为有两个代码 sn-ps,这样我就不会在我的第二个代码中返回承诺?其次,当我做axios.get(CurrencyRateLinkINR).then((response) => { return (时,我没有兑现承诺吗?
  • @KuchBhi 不。除非你return axios.get,否则内部的return 不会返回给调用者。
  • @NoobieSatan 是的,这是另一个问题。好收获!
猜你喜欢
  • 2017-11-05
  • 2019-04-15
  • 2014-06-19
  • 2018-01-14
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多