Асинхронная функция JS ждет вечно - PullRequest
0 голосов
/ 04 июня 2018

Я много читал об асинхронном ожидании, но, очевидно, до сих пор не понимаю.; -)

Я пытаюсь преобразовать следующую структуру обещания .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, но затем программа просто останавливается (без ошибок).Я не буду показывать вам какие-либо другие части приложения, потому что, согласно моему пониманию, эти две функции должны быть эквивалентны - поэтому остальные не должны иметь значения.Видимо я не прав!:-) Что я делаю не так и почему не работает мое решение?

1 Ответ

0 голосов
/ 04 июня 2018

Разница между вашими двумя фрагментами заключается в том, что во втором примере 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')
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...