es6-async await расширенные основы пользовательского интерфейса, написанные от руки (понимание пакетов)

внешний интерфейс JavaScript

Это седьмой день моего участия в ноябрьском испытании обновлений, подробности о мероприятии:Вызов последнего обновления 2021 г."

Несмотря на то, что план последней исповеди закончился, я все еще приветствую ее каждый день, я всегда верю, что если я хорошо к ней отношусь, то однажды я прикоснусь к ней. Я также начал так называемую дорогу собачьего лизания...
Во время разговора с ней я узнал, что она любит завтракать в семье на задворках, но не может вставать каждый день. Тогда я предложил помочь ей принести завтрак. Сначала она немного смутилась и немного отказалась. Позже, после ряда моих уговоров, она согласилась. В тот момент, когда она согласилась, я был счастлив как ребенок. Первый перекресток снаружи , также дал мне бесконечные мечты и ожидания.
Закоулок еще немного далеко.Чтобы лапша не размягчилась,я тоже пошла покупать велосипед.До сих пор помню,что когда купила завтрак в первый раз,завела себе будильник на 6 часов "часы. Я был взволнован, ожидал и нервничал. Я проснулся в 4 часа, а потом потерял сон. Я все думал о том, что сказать ей позже, где ждать, пока она спустится...
На шестой день принося ей завтрак, она сказала, что пришла сюда, но не может слезть. Соседка по комнате помогла ей спуститься. В то время я действительно не понимал этого аспекта, и наши люди чувствовали слишком консервативно. , Это довольно неясно в таких вещах, поэтому я погуглил, а затем сказал ей пить больше воды с коричневым сахаром и больше отдыхать. Во время беседы я из любопытства спросил ее: «Сколько раз в месяц приходит эта тетя?». Это предложение также делало меня шуткой в ​​моем классе колледжа в течение четырех лет, и оно до сих пор обсуждается ими...

Предисловие Советы

Дорогие друзья, эту статью нужно читать внимательно с самого начала, иначе вы не сможете понять асинхронный авит, который я реализовал через функцию генератора* и yield. Внимательно прочитайте пункты знаний пакета, и вы поймете асинхронные генераторы и итераторы.

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

итераторы, генераторы, асинхронность

Итератор: Итератор — это специальный объект, который имеет некоторые проприетарные интерфейсы, специально разработанные для процесса итерации.Все объекты итераторов имеют метод next(), который возвращает объект результата при каждом вызове. Объект результата имеет два свойства: одно — это значение, представляющее следующее возвращаемое значение; другое — выполнено, представляющее собой логическое значение, которое возвращает значение true, когда больше нет данных для возврата. Итератор также содержит внутренний указатель, указывающий на положение значения в текущей коллекции, и каждый раз, когда вызывается метод next(), возвращается следующее доступное значение.

Как определить, может ли он быть повторен или нет
     let arr=[1,2,3]
     let str='123'
     let obj={a:1,b:2}
     
     for(var i of arr){
         console.log('数组',i)
     }

     for(var i of str){
         console.log('字符串',i)
     }

     for(var i of obj){
         console.log('对象',i)
     }

Результат печати показан ниже

image.png

Описание: Объект не является итерируемым

Вы можете увидеть, поддерживает ли тип итерацию из прототипа, взяв в качестве примера строки.

image.pngРазверните прототип строки, и вы обнаружите, что он существует.Symbol(Symbol.iterator)Это свойство указывает, что оно является итерируемым.

Используя это свойство в сочетании с описанием итераторов, вы сможете лучше понять итераторы.
кlet str1='舔狗的泪'Например

image.png

Вручную реализовать эффект итератора Возьмем объект в качестве примера
   var obj = {
      a: 1,
      b: 2,
      c: 3,
      [Symbol.iterator]() {
        var index = 0;
        let map = new Map([
          ["a", 1],
          ["b", 2],
          ["c", 3],
        ]);
        return {
          next() {
            let mapEntries = [...map.entries()];//将它还原成二维数组
            if (index < map.size) {
              return {
                value: mapEntries[index++],
                done: false,
              };
            } else {
              return { value: undefined, done: true };
            }
          },
        };
      },
    };
    let iter=obj[Symbol.iterator]()

При тестировании будет обнаружено, что этот объект может поддерживать

image.png

image.png

разница между обходом и итерацией

Итерация: извлекайте данные один за другим из целевого источника последовательно. Целевой источник упорядочен, непрерывен
Обход: пока данные можно зацикливать, их не нужно упорядочивать.
Поскольку объектный цикл не упорядочен, его нельзя повторять, но Map может поддерживать итерацию.

Строитель

* перед функцией указывает, что генератор использует yield для получения значения.

  function * test(){
      yield 1
      yield 2
      yield 3
    }
  var iter=test()
  iter.next()
  //输出 {value:1,done:false}

Iter также может пройти цикл for of, что здесь не показано.

注意: Каждый раз, когда вызывается next, он будет переходить к выходу, следующий код не будет печатать лог

  function * test(){
      console.log('舔狗的泪')
      yield 1
      yield 2
      yield 3
    }
  var iter=test()
  //要调用iter.next()才会走console.log 

Замените выход генератора на возврат, чтобы увидеть разницу:

image.png

На основе yield для преобразования метода, который только что сделал объект итерируемым
     var obj = {
        a: 1,
        b: 2,
        c: 3,
        [Symbol.iterator]:function * () {
          var index = 0;
          let map = new Map([
            ['a', 1],
            ['b', 2],
            ['c', 3]
          ]);
          let mapEntries = [...map.entries()]; //将它还原成二维数组
          while(index<mapEntries.length){
            yield mapEntries[index++]
          }
        }
      };
      let iter = obj[Symbol.iterator]();
Передать параметры следующему методу, увидеть уродливую сторону yield, асинхронную предыдущую жизнь
      function* test() {
        let value1 = yield 1;
        console.log('value1',value1);
        let value2 = yield 2;
        console.log('value2',value2);
        let value3 = yield 3;
        console.log('value3',value3);
      }
      var iter=test()
      iter.next('one')
      iter.next('two')
      iter.next('three')
      iter.next('')

image.pngАнализ результатов: значение в следующем будет присвоено значению последней доходности.
С точки зрения разработчика более ожидаемо, что значение, напечатанное value1, равно 1. асинхронный жду его

асинхронное ожидание основных операций

Обычное использование асинхронного ожидания:let x=await 异步请求
Посмотрите на другое использование этого, просто посмотрите на картинку и говорите:

     function b() {
        return new Promise(resolve => {
          setTimeout(() => resolve(1), 1000);
        });
      }
      async function a() {
        let value = await b();
        console.log(value);
      }
      a();
      //1秒后打印1
     function b(){
        return 1
      }
      async function a() {
        let value = await b();
        console.log(value);
      }
      a();
      //打印1
      function b() {
        let c = 1;
      }
      async function a() {
        let a = await b();
        console.log(a);
      }
      a();
       //打印undefined
Реализуйте асинхронность на основе * yield

Сделайте это на следующем примере:

      let num=1
      //b函数只为模拟一个axios
      function b() {
        return new Promise(resolve => {
          setTimeout(() => resolve(num++), 1000);
        });
      }
      async function a() {
        let value1 = await b();
        let value2 = await b();
        let value3 = await b();
        console.log(value1,value2,value3);
        return value3
      }
      let promise =a();
      //3秒后打印 1,2,3

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

      let num = 1;
      function b() {
        return new Promise(resolve => {
          setTimeout(() => resolve(num++), 1000);
        });
      }
      function* a() {
        let value1 = yield b();
        let value2 = yield b();
        let value3 = yield b();
        console.log(value1, value2, value3);
        return value3
      }
      function Co(iter) {
      //因为async方法内部包裹的就是Promise,所以这里也return一个Promise
        return new Promise((resolve, reject) => {
          let next = function (data) {
            let { value, done } = iter.next(data);
            if (done) {
              resolve(data);
            } else {
            //兼容b函数是一个非异步操作
            value instanceof Promise?
              value.then(val => {
                next(val);
              }, reject):next(value);
            }
          };
          next();
        });
      }
     let promise = Co(a());
Личное понимание и резюме

итератор: его прототип существует вышеSymbol(Symbol.iterator), который может использоваться циклом for
Генератор: * функция с доходностью
Как только вы поймете функции генератора, реализация асинхронного ожидания на их основе станет легкой.
В настоящее время написана базовая реализация класса Map Set Promise в es6.

Предыдущий пост: Реализация обещания в 72 строкиНаггетс.Талант/пост/702689…