Почему setState в этом промисе обновляется дольше, чем тот же код асинхронной функции?

У меня тут 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 []

Оба результата console.info(this.state.postList); относятся не к текущим извлеченным данным, а к более раннему состоянию. Состояние будет обновлено позже — асинхронный характер setState.

xadm 28.05.2019 00:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
35
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Первая функция является асинхронной. В асинхронной функции код приостанавливается, пока выполняются ожидаемые промисы.

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 27.05.2019 23:59

@MatijaxD … это одна из самых запутанных частей javascript, и к ней нужно время, чтобы привыкнуть.

Mark 28.05.2019 00:00

Если вы хотите зарегистрировать обновленное состояние, вы должны дождаться промиса для разрешения некоторых данных, только когда у вас есть данные, вы можете регистрировать сами данные:

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
}

Другие вопросы по теме