ES2017 - Принцип асинхронного ожидания

ECMAScript 6
ES2017 - Принцип асинхронного ожидания

Для тех, кто не знаком с Generator, вы можете сначала просмотреть документацию Generator:developer.Mozilla.org/this-cn/docs/…

предисловие

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

function getJSONFile() {
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve({
        name: '大漠传奇',
        age: 23,
      })
    }, 1000)
  })
}

function getHobby() {
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve({
        hobby: ['爬山','旅游','听歌','看电影','看小说','打游戏'],
      })
    }, 1000)
  })
}

function* gen(i) {
  let me = yield getJSONFile();
  console.log('me:', me);
  let hobby = yield getHobby();
  console.log('hobby:', hobby)
}

function co(genFn) {
  let gen = genFn();
  let res = gen.next()
  let run = (gen, res) => {
    if(!res.done){
      if(res.value&&(res.value.__proto__.constructor === Promise)){
        res.value.then((data) => {
          let res2 = gen.next(data)
          run(gen, res2);
        })
      }else{
        let res3 = gen.next(res.value);
        run(gen, res3);
      }
    }
    
  }
  run(gen, res);
}

co(gen)

Однако после того, как ES2017 предоставит async && await, приведенный выше код можно будет написать более элегантно. Например:

// async await
async function likeGen() {
  let me = await getJSONFile();
  console.log('me:', me);
  let hobby = await getHobby();
  console.log('hobby:', hobby);
  return 'end';
}

likeGen().then(res => {
  console.log('res:', res);
})

Если сравнить их с использованием async+await для записи, наиболее очевидным изменением будет то, что на одну функцию co меньше, а объем кода будет меньше. Остальной код похож на реализацию генератора. Так почему же ES2017 предоставляет async && await для написания синхронного кода с меньшим количеством кода и большим удобством?

Давайте представим конкретные причины ниже.Давайте сначала посмотрим на введение функции async && await.

async && a ждать функций

async

Объявление асинхронной функции используется для определения асинхронной функции, которая возвращает объект AsyncFunction. Асинхронная функция — это функция, которая выполняется асинхронно через цикл обработки событий и возвращает результат через неявное обещание. Но если ваш код использует асинхронные функции, его синтаксис и структура будут больше похожи на стандартные синхронные функции.

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

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

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

await

Оператор await используется для ожидания объекта Promise. Его можно использовать только в асинхронных функциях.

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

Если обещание обработано, выражение AWAIT выдаст причину проксимации обещания.

Кроме того, если значение выражения, следующего за оператором await, не является промисом, возвращается само значение.

async+await VS generator

Цель введения async и await в ES2017 — упростить утомительное использование генераторов для написания синхронного кода, уменьшить сложность использования js для написания синхронного кода, уменьшить объем кода и упростить синтаксис.

Вы можете понять асинхронность и ждать, когдапредисловиеПервая половина средней части использует генератор для реализации простого синтаксического сахара верхнего уровня синхронного кода. То есть браузер помогает нам реализовать базовую часть в интерпретаторе js.Когда мы используем async и await, интерпретатор js будет понимать это как функцию генератор+со (генератор автоматически выполняет функцию, реализованную в предисловии).

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