Я недавно закончил учебный курс по разработке программного обеспечения в школе Flatiron. На протяжении всей программы я погрузился в Ruby, Rails, Sinatra, JavaScript, React и Redux. Я узнал, что каждый язык/фреймворк имеет свои уникальные проблемы. «Стек вызовов» JavaScript был одной из самых сложных концепций для понимания, однако он является неотъемлемой частью оптимизированного взаимодействия с пользователем.

JavaScript является однопоточным, что означает, что в момент выполнения кода происходит только одно действие. Механизм JavaScript отслеживает, где он находится в коде, используя стек вызовов. Когда несколько синхронных функций вызываются одновременно, функции добавляются в стек в том порядке, в котором они были вызваны. Как только функция возвращается, она «выталкивается» из стека вызовов, и выполняется следующая функция.

На изображении ниже объявляются и вызываются три функции (A, B, C).

В приведенном выше примере демонстрируется синхронный блок кода, в котором каждый раздел кода выполняется по одному, в определенной последовательности. Каждая функция вызывается и добавляется в стек вызовов по порядку, и поскольку они являются синхронными запросами, данные записываются в консоль, как и ожидалось. Синхронные функции отлично подходят для простых задач, но могут быть проблематичными для функций, выполнение которых занимает много времени. Последнее, чего хочет пользователь, — это смотреть на пустой экран и думать, загрузится ли страница!

Итак, если JavaScript способен выполнять только одну команду за раз, как мы можем избежать зависания из-за медленного кода?

К счастью для нас, браузер может обрабатывать асинхронные запросы в фоновом режиме, не останавливая и не «блокируя» выполнение другого кода. Когда механизм JavaScript распознает асинхронный запрос, он передает его для выполнения браузером. Синхронный код является «блокирующим», в то время как асинхронный код является «неблокирующим», что означает, что другой код может выполняться до того, как функция будет возвращена. Асинхронные запросы не добавляются в стек вызовов до тех пор, пока они не будут возвращены, и стек вызовов не станет пустым.

Примером асинхронного запроса является выборка. В приведенном ниже примере функция handleSubmit вызывается при отправке формы для создания нового события. Я включил журналы консоли, чтобы продемонстрировать порядок выполнения кода. Основываясь на том, что вы знаете о синхронных и асинхронных запросах, как вы думаете, что мы увидим в консоли?

handleSubmit = event => {
  event.preventDefault();
  console.log('Before create event')
  this.createEvent();
  console.log('After createEvent')
}
createEvent = () => {
  console.log('Making fetch request')
  return fetch('http://localhost:3001/events', {
    method: 'POST',
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({event:
      {
        name: this.state.name,
        start_time: this.state.start_time,
        end_time: this.state.end_time,
        location: this.state.location,
        address: this.state.address,
        notes: this.state.notes,
        invited_user_ids: this.state.invited_user_ids,
      }
    })
  })
  .then(res => {
    if(res.ok) {
    console.log('successful response')
    return res.json()
  } else {
    return res.json().then(errors => Promise.reject(errors))
    }
  })
}

Вы были правы? Как видите, асинхронный запрос на выборку регистрируется в консоли последним.

День за днем ​​я восхищаюсь сложностью и возможностями Интернета. Во время учебы в школе Flatiron я узнал, что важно понимать стек вызовов JavaScript и использовать как синхронный, так и асинхронный код для создания наилучшего взаимодействия с пользователем.