JS异步功能永远等待着

tin*_*ing 1 javascript async-await

我已经阅读了很多关于异步等待的内容,但显然我仍然没有得到它.;-)

我试图将以下.then promise结构转换为异步等待:

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')
}
Run Code Online (Sandbox Code Playgroud)

我的结果是:

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')
}
Run Code Online (Sandbox Code Playgroud)

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

CRi*_*ice 5

两个片段之间的区别在于,在第二个async/await示例中,您获取目标和待办事项之前,您不会订阅商店,而在第一个示例中,您立即订阅.

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

store.dispatch(receiveDataAction(todos, goals))
Run Code Online (Sandbox Code Playgroud)

之前被称为

store.subscribe(() => this.forceUpdate())
Run Code Online (Sandbox Code Playgroud)

并且由于该点已经调度了该操作,因此永远不会调用订阅回调.

要解决此问题,您可能只想移动订阅部分,以便在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')
}
Run Code Online (Sandbox Code Playgroud)