【问题标题】:React - Why functions ignores await?React - 为什么函数忽略等待?
【发布时间】:2020-05-18 19:28:27
【问题描述】:

我的目标是在前一个完成后一个一个地执行这些功能,并在这些功能正在进行的同时激活某种加载。

相反,在这个可加载组件之后,所有函数都会忽略等待进程。

为什么会发生这种情况,以及当前一个功能完成后,我如何才能开始使用该功能?我正在尝试在componentDidMount() 中完成所有这些工作。我有 @babel 依赖 v7+。

在控制台中可见,这个 async/await 函数被忽略并且 loadableComponent 在所有函数启动之前完成。

编辑:更可重复的示例:

"base_coponent"(定义了扩展 React.Component 的 LoadableComponent)

export class LoadableComponent extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        loading: true,
        loading_counter: 0
    }
}

activateLoad() {
    let i = this.state.loading_counter
    console.log("setting loading", this.state)
    this.setState({loading: true, loading_counter: i + 1 }, function () {
        console.log("after setting loading counter", this.state)
    })
}

deactivateLoad() {
    let i = this.state.loading_counter
    console.log("in deactivateLoad", this.state)
    if (i == 1) {
        console.log("disabling loading")
        this.setState({ loading: false, loading_counter: 0 })
    } else if (i <= 0) {
        console.log("disabling loading")
        this.setState({ loading: false, loading_counter: 0 })
    } else {
        console.log("setting loading")
        this.setState({ loading: true, loading_counter: i - 1 })
    }

}

用户操作(从哪里导出函数 getAppuser() 和其他函数)

export function getAppuser(appuser) {
return dispatch => { 
    let url = `${config.server}/fs/data/getAppuser/${appuser}`
    axios.get(url).then((data) => {

        dispatch({type: list.user.GET_APPUSER, data: data.data})            
    }).catch(
        err => {
            console.error(err)
        }
    )
}

“index”(发生的地方。特别是类 Content 扩展 LoadableComponent)

1) 定义异步可加载

async loadable(b, e = (err) => { console.error(err) }) {
    this.activateLoad()
    try {
        await b()
        this.deactivateLoad()
    } catch (err) {
        this.deactivateLoad()
        e(err)
    }
}

2) componentDidMount()

this.loadable(async () => {

      try {

        console.log("start of Loadable")

        await this.props.dispatch(getAppuser(appuserID))
        await this.props.dispatch(getSettings(appuserID))
        await this.props.dispatch(getAppuserRank(period))

        console.log("in the end of Loadable")
      } catch (err) {

        console.log(err)
      }

  })

package.json 只是所有依赖项和 devdependencies 中的一部分,在我的案例中,我发现其他一些教程也很重要

"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.9.6",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.9.6",
"babel-loader": "^8.0.0",
"babel-plugin-add-module-exports": "^0.3.2",
"babel-plugin-react-html-attrs": "2.0.0",

控制台日志当我应用来自 Bergeron 主题的逻辑时 - 这个控制台日志和我放在顶部的控制台日志之间的区别是,“设置加载计数器后”的日志不再可见,这对我来说是不对的。

尝试 1)试图创建:用户操作中的新承诺。但在这种情况下,我得到一个错误,即 Actions 必须是普通对象。使用自定义中间件进行异步操作。

export function getAppuser(appuser) {
return new Promise(function (resolve, reject) {
    return dispatch => { 
        let url = `${config.server}/fs/data/getAppuser/${appuser}`
        axios.get(url).then((data) => {

            dispatch({type: list.user.GET_APPUSER, data: data.data})            
        }).catch(
            err => {
                console.error(err)
            }
        )
    }
})

【问题讨论】:

  • 不是真的。当我在本主题中应用逻辑时,没有任何变化。但我不确定 a 是否做的一切都与示例相同。你确定,这个逻辑在调度上与 setstate 一样工作吗?我是一个相当初学者,所以也许我在说 shi*s。对不起:(
  • 您已经在setState 之后的activateLoad 中放置了一个控制台日志,这肯定永远不会记录更新的值。 Quentin's answer 也是正确的,但这是您的问题的猜测,缺少minimal reproducible example
  • 好的,我尝试在 activateLoad 中应用该示例,但现在没有任何显示。我的意思是“设置加载计数器后”不再有可见的日志。我将在下一条评论中添加更详细的问题示例。谢谢
  • 从您的回答中,我看到您未能正确实现 setState 回调。现在,回调看起来甚至不是setState 的参数,这可以解释您的最后一条评论,它从未被调用,因为它从未正确传递。

标签: javascript reactjs async-await


【解决方案1】:

可能dispatch 不会返回承诺。如果是,则无法根据传递给它的值进行解析(因为传递给dispatch 的所有值都是undefined)。

你只能有用地await 一个承诺。

【讨论】:

  • 好的,如果我做对了,只有承诺可以“等待”。我尝试了更改导出函数,我在 this.props.dispatch(getAppuser... 中调用它来返回 new Promise(dispatch => {axios... 看来,该函数现在以正确的顺序调用,但没有人被处理,因为出现错误“操作必须是普通对象。使用自定义中间件进行异步操作”
猜你喜欢
  • 2021-06-17
  • 2021-04-17
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多