【问题标题】:JS async function awaits foreverJS异步函数永远等待
【发布时间】:2018-06-04 16:45:03
【问题描述】:

我已经阅读了很多关于异步等待的内容,但显然我仍然不明白。 ;-)

我正在尝试将以下 .then 承诺结构转换为异步等待:

componentDidMount() {
    const { store } = this.props

    Promise.all([
      API.fetchTodos(),
      API.fetchGoals(),
    ]).then(([ todos, goals ]) => {
      store.dispatch(receiveDataAction(todos, goals))
    })

    store.subscribe(() => this.forceUpdate())

    console.log('test')
}

我的结果是:

async componentDidMount() {
    const { store } = this.props

    const [todos, goals] = await Promise.all([
      API.fetchTodos(),
      API.fetchGoals(),
    ])

    store.dispatch(receiveDataAction(todos, goals))

    store.subscribe(() => this.forceUpdate())

    console.log('test')
}

结果是这个函数永远不会结束。它调用包括console.log 在内的所有内容,但随后程序就停止了(没有错误)。我没有向您展示应用程序的任何其他部分,因为根据我的理解,这两个功能应该是等效的 - 所以其余的应该无关紧要。显然我错了! :-) 我做错了什么,为什么我的解决方案不起作用?

【问题讨论】:

    标签: javascript async-await


    【解决方案1】:

    您的两个 sn-ps 之间的区别在于,在第二个 async/await 示例中,直到 您获取了目标和待办事项之后,您才订阅商店,而在首先,您立即订阅。

    所以你的第二个例子不起作用,因为现在你已经保证了

    store.dispatch(receiveDataAction(todos, goals))
    

    之前调用
    store.subscribe(() => this.forceUpdate())
    

    由于此时操作已经被调度,订阅回调永远不会被调用。

    要解决此问题,您可能只想移动订阅部分,使其在 await 调用之前发生。这样,您在承诺解决之前就已经订阅了。所以是这样的:

    async componentDidMount() {
        const { store } = this.props
    
        // Move to the front so this happens before the await.
        store.subscribe(() => this.forceUpdate())
    
        const [todos, goals] = await Promise.all([
          API.fetchTodos(),
          API.fetchGoals(),
        ])
    
        store.dispatch(receiveDataAction(todos, goals))
    
        console.log('test')
    }
    

    【讨论】:

    • 哦,所以我对 await 工作原理的理解并没有错。好的,但是现在让我们假设(同步)订阅调用需要很长时间,所以在这种情况下,您可能不想将其移到顶部,因为您想立即开始异步获取,然后在您使用时间时等待重同步操作的响应。在这种情况下,第一个示例正是您想要的,但它如何与 async await 一起工作?
    猜你喜欢
    • 2019-09-04
    • 1970-01-01
    • 2018-12-14
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多