У меня тут 2 версии одних и тех же функций выборки, первая использует промисы, вторая асинхронно-ожидание. Насколько я понимаю, между этими двумя не должно быть никакой разницы, поэтому я был бы признателен за некоторые разъяснения того, что на самом деле здесь происходит.
В следующей версии, в которой используется async-await, состояние устанавливается при запуске журнала консоли времени:
async fetchPostList(query) {
const response = await fetch(`https://hacker-news.firebaseio.com/v0/${query}.json`)
const data = await response.json()
this.setState({ postList: data });
console.info(this.state.postList);
}
Консоль: Array(474) [ ... ]
Версия, которая использует обещания, устанавливает состояние после журнала консоли:
fetchPostList(query) {
fetch(`https://hacker-news.firebaseio.com/v0/${query}.json`)
.then( response => response.json())
.then( data => this.setState({ postList: data }))
console.info(this.state.postList);
}
Консоль: Array []
Первая функция является асинхронной. В асинхронной функции код приостанавливается, пока выполняются ожидаемые промисы.
async fetchPostList(query) {
const response = await fetch(`https://hacker-news.firebaseio.com/v0/${query}.json`)
/* Pause ...*/
const data = await response.json()
/* Pause ... */
this.setState({ postList: data });
console.info(this.state.postList);
}
Вторая функция не является асинхронной, что означает, что она выполняется до завершения. Он просто запускает промисы и обратные вызовы и продолжает работу, поэтому console.info()
вызывается сразу после создания промисов.
fetchPostList(query) {
fetch(`https://hacker-news.firebaseio.com/v0/${query}.json`)
.then( response => response.json())
.then( data => this.setState({ postList: data }))
/* does NOT pause */
console.info(this.state.postList);
}
Я чувствую себя немым сейчас, я думал, что оба остановились. Большое спасибо за ответ!
@MatijaxD … это одна из самых запутанных частей javascript, и к ней нужно время, чтобы привыкнуть.
Если вы хотите зарегистрировать обновленное состояние, вы должны дождаться промиса для разрешения некоторых данных, только когда у вас есть данные, вы можете регистрировать сами данные:
fetchPostList(query) {
fetch(`https://hacker-news.firebaseio.com/v0/${query}.json`)
.then( response => response.json())
.then( data => {
this.setState({ postList: data })
// here you have data
console.info(this.state.postList);
})
// here you do not have data
}
Оба результата
console.info(this.state.postList);
относятся не к текущим извлеченным данным, а к более раннему состоянию. Состояние будет обновлено позже — асинхронный характерsetState
.