Рубрики
Без рубрики

Современный асинхронный JavaScript с асинхронностью и ожиданием

Откройте для себя современный подход к асинхронным функциям в JavaScript. JavaScript эволюционировал за очень короткое время от обратных вызовов до обещаний, и с ES2017 асинхронный JavaScript стал еще проще с синтаксисом async/await

  • Вступление
  • Почему были введены async/await?
  • Как это работает
  • Краткий пример
  • Обещай все то, что
  • Код намного проще для чтения
  • Несколько асинхронных функций последовательно
  • Более простая отладка

Вступление

JavaScript эволюционировал за очень короткое время от обратных вызовов до обещаний (ES2015), и с ES2017 асинхронный JavaScript стал еще проще с синтаксисом async/await.

Асинхронные функции представляют собой комбинацию обещаний и генераторов , и в основном они представляют собой абстракцию более высокого уровня по сравнению с обещаниями. Позвольте мне повторить: async/await построен на обещаниях .

Почему были введены async/await?

Они уменьшают шаблонность вокруг обещаний и ограничение “не разрывайте цепь”, связывающее обещания.

Когда в ES2015 были введены обещания, они предназначались для решения проблемы с асинхронным кодом, и они это сделали, но за 2 года, разделявшие ES2015 и ES2017, стало ясно, что обещания не могут быть окончательным решением .

Обещания были введены для решения знаменитой проблемы ад обратного вызова , но они сами по себе усложнили и усложнили синтаксис.

Это были хорошие примитивы, вокруг которых разработчики могли бы использовать лучший синтаксис, поэтому, когда пришло время, мы получили асинхронные функции .

Они заставляют код выглядеть синхронным, но он асинхронен и не блокируется за кулисами.

Как это работает

Асинхронная функция возвращает обещание, как в этом примере:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

Когда вы хотите позвонить эта функция, которую вы добавляете ожидание и вызывающий код остановится до тех пор, пока обещание не будет выполнено или отклонено . Одно предостережение: клиентская функция должна быть определена как асинхронная . Вот пример:

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

Краткий пример

Это простой пример асинхронности/ожидания, используемый для асинхронного запуска функции:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

console.log('Before')
doSomething()
console.log('After')

Приведенный выше код выведет на консоль браузера следующее:

Before
After
I did something //after 3s

Обещай все то, что

Добавление ключевого слова async к любой функции означает, что функция вернет обещание.

Даже если он не делает этого явно, он внутренне заставит его вернуть обещание.

Вот почему этот код действителен:

const aFunction = async () => {
  return 'test'
}

aFunction().then(alert) // This will alert 'test'

и это то же самое, что:

const aFunction = async () => {
  return Promise.resolve('test')
}

aFunction().then(alert) // This will alert 'test'

Код намного проще для чтения

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

И это очень простой пример, основные преимущества возникнут, когда код будет намного сложнее.

Например, вот как вы могли бы получить ресурс JSON и проанализировать его, используя обещания:

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => userResponse.json()) // parse JSON
}

getFirstUserData()

И вот та же функциональность, предоставляемая с помощью await/async:

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await userResponse.json() // parse JSON
  return userData
}

getFirstUserData()

Несколько асинхронных функций последовательно

Асинхронные функции могут быть объединены в цепочку очень легко, а синтаксис гораздо более удобочитаем, чем при использовании простых обещаний:

const promiseToDoSomething = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 10000)
  })
}

const watchOverSomeoneDoingSomething = async () => {
  const something = await promiseToDoSomething()
  return something + ' and I watched'
}

const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
  const something = await watchOverSomeoneDoingSomething()
  return something + ' and I watched as well'
}

watchOverSomeoneWatchingSomeoneDoingSomething().then(res => {
  console.log(res)
})

Будет печатать:

I did something and I watched and I watched as well

Более простая отладка

Отладка обещаний сложна, потому что отладчик не будет переступать через асинхронный код.

Async/await делает это очень простым, потому что для компилятора это похоже на синхронный код.

Оригинал: “https://flaviocopes.com/javascript-async-await/”