Почему Async всегда возвращает обещание? - PullRequest
0 голосов
/ 01 января 2019

Этот вопрос теоретический - у меня нет конкретной проблемы для решения.

С учетом сказанного, почему ключевое слово async переносит возвращаемое значение асинхронной функции в обещании?В чем смысл?Это ТОЛЬКО потому, что выражение await ожидает обещание?Или есть какое-то значение / использование за этим решением?

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Я подумал, что отвечу на это прежде всего потому, что асинхронность в Javascript раньше приводила меня в замешательство, и внезапно это прекратилось, поэтому я надеюсь, что эта аналогия может помочь вам в этом.

У вас есть асинхронное событие.Это может быть что угодно, получение чего-либо с сервера, выполнение чего-либо в браузере, что требует времени, обучение модели машинного обучения (!), Выполнение функции или метода, использующего setTimeout и т. Д.

Красота Javascriptи основная причина того, что он работает так хорошо для браузера, заключается в том, что он использует поток процессора, на котором он работает, очень умным способом, который предотвращает блокировку потока процессами, которые занимают время (как те, что упомянуты выше)

Многие другие языки, например Ruby, работают более чем в одном потоке.Можно использовать сервисные работники для запуска процессов в нескольких потоках в javascript, но это выходит за рамки этого ответа!

Асинхронная природа цикла событий JS позволяет потоку «выключаться» и что-то делатьв то время как он ожидает завершения процесса.

Проблема с этим с точки зрения программирования заключается в том, что в коде возможно, что что-то, основанное на результате блокирующего события, получит 'undefined'в результате события, если оно не ожидает завершения события, прежде чем попытается использовать его результат.Возьмите этот фрагмент кода ниже

let scopedVariable
console.log('the code has started')
setTimeout(() => {
  scopedVariable="I am the result of some async process"
}, 5000);
console.log(scopedVariable)

Когда код достигает журнала консоли, setTimeout еще не завершен.Так как setTimeout устанавливает scopedVariable только после его завершения, переменная не определена, когда мы регистрируем ее

, если, однако,

Мы завершим тайм-аут в обещании, которое мы можем ожидать, пока он не получит ответ callback (первый аргументобещание), и код будет «приостанавливаться», пока обещание не достигнет обратного вызова разрешения, прежде чем продолжить.

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

let scopedVariable
const asyncEvent = new Promise ((resolve,fail) => {
  setTimeout(() => {
    resolve(scopedVariable="I have resolved")
  }, 5000);
})
const container = async () => {
  const result = await asyncEvent
  console.log(scopedVariable)
}

container()

Вы можете использовать await и .then взаимозаменяемо

Например, мы можем пойти:

let scopedVariable
const asyncEvent = new Promise ((resolve,fail) => {
  setTimeout(() => {
    resolve(scopedVariable="I have resolved")
  }, 5000);
})
const container = async () => {
  asyncEvent.then(() => console.log(scopedVariable))
}

container()

еще раз, код будет приостановленв .then, а затем продолжить, когда обещание asyncEvent разрешилось.

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

let scopedVariable
const asyncEvent = new Promise ((resolve,fail) => {
  setTimeout(() => {
    resolve(scopedVariable="I have resolved")
  }, 5000);
})

asyncEvent.then(() => console.log(scopedVariable))

Самое замечательное в .then заключается в том, что сопровождающий .catch позволяет вам отследить любые ошибки, вызванные асинхронным событием (например, еслиng что-то с сервера, когда есть ошибка).Для асинхронного ожидания вам нужно обернуть потенциально опасные функции в try catch.

Чтобы использовать ожидание, вы должны быть внутри асинхронной функции (отсюда и функция асинхронного контейнера выше).Это не обязательно с .then, но цепочки .then и .catch могут сделать ваш код неопрятным.

Надеюсь, это поможет!

0 голосов
/ 01 января 2019

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

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

Использование await перед асинхронным вызовом функции приостанавливает текущую функцию до тех пор, пока обещание, которое она возвращает, не будет разрешено.По сути это эквивалентно переносу оставшейся части функции в анонимную функцию и ее использованию в качестве обратного вызова .then() для обещания.

Для получения дополнительной информации об отношениях см. Как перевести код Promiseдо асинхронного ожидания

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