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

Реализация Async и ждут с генераторами

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

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

Оказывается довольно просто, так как поведение async и ждать можно легко эмулировать с использованием генераторов. Давайте посмотрим!

Идти вперед, клонировать Репозиторий И давайте начнем.

Генераторы

Я собираюсь полагать, что у вас мало кто не испытывает опыта с генераторами, честно говоря, большую часть времени они не особенно полезны, и вы можете легко управлять без них. Так что не волнуйтесь – мы начнем с быстрой напоминания.

Генераторы – это объекты, созданные Функции генератора – Функции с * (Звездочка) рядом с их именем.

Эти генераторы имеют удивительную способность, которые позволяют нам остановить выполнение кода – всякий раз, когда мы хотим – с помощью ключевого слова урожай .

Рассмотрим этот пример:

const generator = (function*() {
  // waiting for .next()
  const a = yield 5;
  // waiting for .next()
  console.log(a); // => 15
})();

console.log(generator.next()); // => { done: false, value: 5 }
console.log(generator.next(15)); // => { done: true, value: undefined }

Учитывая, что это абсолютные основы, я бы порекомендовал, прежде чем вы прокрутите дальше, вы читаете Эта статья Чтобы понять, что на самом деле здесь происходит.

Если вы чувствуете, что у вас есть сильное понимание основных идей, мы можем двигаться дальше.

Держись, жду минуты

Разве вы не задумались, как ждать Действительно работает?

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

То, что мы могли бы сделать, это просто принять каждую полученную ценность, поставить его в обещание, а затем ждать, пока обещание будет решено. После этого мы просто вернемся на генератор, позвонив Generator.Next (Res RevingValue).

Звучит как план. Но сначала, давайте напишем некоторые тесты, чтобы убедиться, что все работает, как ожидалось.

Что наше Asynq Функция должна сделать:

  • ждать асинхронного кода, прежде чем продолжить выполнение
  • вернуть Обещание с возвращенным значением из функции
  • сделать попробуйте/поймать Работа над асинхронным кодом

Примечание: потому что мы используем генераторы, наши ждать становится доходность Отказ

import { asynq } from '../src';

describe('asynq core', () => {
  test('Waits for values (like await does)', () => {
    return asynq(function*() {
      const a = yield Promise.resolve('a');
      expect(a).toBe('a');
    });
  });

  test('Catches the errors', () => {
    return asynq(function*() {
      const err = new Error('Hello there');

      try {
        const a = yield Promise.resolve('a');
        expect(a).toBe('a');

        const b = yield Promise.resolve('b');
        expect(b).toBe('b');

        const c = yield Promise.reject(err);
      } catch (error) {
        expect(error).toBe(err);
      }

      const a = yield Promise.resolve(123);
      expect(a).toBe(123);
    });
  });

  test('Ends the function if the error is not captured', () => {
    const err = new Error('General Kenobi!');

    return asynq(function*() {
      const a = yield Promise.reject(err);
      const b = yield Promise.resolve('b');
    }).catch((error) => {
      expect(error).toBe(err);
    });
  });

  test('Returns a promise with the returned value', () => {
    return asynq(function*() {
      const value = yield Promise.resolve(5);
      expect(value).toBe(5);

      return value;
    }).then((value) => {
      expect(value).toBe(5);
    });
  });
});

Хорошо, отлично! Теперь мы можем говорить о реализации.

Наше Asynq Функция принимает в качестве параметра генератор функции – вызывая его, мы создаем генератор.

Просто чтобы быть уверенным, мы называем Isgeneratoratore которые проверяют, является ли полученное значение объектом и имеет методы Следующий и бросить Отказ

Затем рекурсивно мы потребляем каждый урожай ключевое слово, позвонив Generator.Next (EndedValue). Мы ждем возвращенного обещания быть урегулированным, а затем вернуть свой результат обратно в генератор, повторяя весь процесс.

Мы также должны прикрепить поймать Обработчик, так что, если функция бросает исключение, мы можем поймать его и вернуть исключение внутри функции, позвонив Генератор. Строу (ошибка) Отказ

Теперь любые потенциальные ошибки будут обрабатываться поймать Отказ Если бы не было попробуйте/поймать Блок на месте, ошибка Просто остановит выполнение всего – как любое необработанное исключение – и наша функция вернет бы отклоненное обещание.

Когда генератор сделан, мы возвращаем возвращаемое значение генератора в обещании.

import { isGeneratorLike } from './utils';

type GeneratorFactory = () => IterableIterator;

function asynq(generatorFactory: GeneratorFactory): Promise {
  const generator = generatorFactory();

  if (!isGeneratorLike(generator)) {
    return Promise.reject(
      new Error('Provided function must return a generator.'),
    );
  }

  return (function resolve(result) {
    if (result.done) {
      return Promise.resolve(result.value);
    }

    return Promise.resolve(result.value)
      .then((ensuredValue) => resolve(generator.next(ensuredValue)))
      .catch((error) => resolve(generator.throw(error)));
  })(generator.next());
}

Теперь, пройдя наши тесты, мы видим, что все работает, как ожидалось.

Упаковка

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

Не стесняйтесь переходить по коду снова. Чем лучшее ваше понимание основных идей, тем больше вы сможете оценить блеск создателей async и Ждите ключевые слова.

Большое спасибо за чтение! Я надеюсь, что вы нашли эту статью информацию. Я также надеюсь, что это помогло, что вы не увидите, что в async. и Ждите Ключевые слова и что их можно легко заменять генераторами.

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

Проверьте мой Социальные СМИ Действительно

Присоединяйтесь к моей рассылке Действительно

Первоначально опубликовано www.mcieslar.com 6 августа 2018 года.

Оригинал: “https://www.freecodecamp.org/news/how-to-implement-async-and-await-with-generators-11ab0859010f/”