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

Асинхронные итераторы в JavaScript

Асинхронистые итераторы похожи на итераторы, но на этот раз следующий () возвращает обещание.

Автор оригинала: Tiago Lopes Ferreira.

Итализация за сбор ценностей это очень распространенная операция. И для этого JavaScript предоставляет итерационные интерфейсы, такие как для петлей , карта () и Фильтр () Отказ

С Ecmascript 2015 Концепция итерации стала частью ядра JS с внедрением Итераторы и генераторы Отказ

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

Для этого итератор предоставляет метод под названием Далее () Отказ Когда звонит, Далее () Возвращает следующий элемент в коллекции. В основном, кортеж {Значение, сделано} , где:

  • ценность это следующее значение в коллекции
  • сделано является логией, который указывает, закончится ли итерация
function myIterator() {
  var array = [1, 2];
  return {
    next: function() {
      if (array.length) {
        return {
          value: array.shift(),
          done: false
        };
      } else {
        return {
          done: true
        };
      }
    }
  };
}

var iterator = myIterator();
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { done: true }

Нам, вероятно, не нужно будет реализовать итератор с нуля. Их создание требует дополнительной помощи в связи с необходимостью Явно управляйте государством Отказ

Это где Генераторы пригодиться.

giphy.gif.gif.

Генератор является фабричной функцией итераторов и мощная альтернатива для создания итератора.

Это позволяет нам построить итератор, определив одну функцию, которая поддерживает состояние итератора самостоятельно.

function* myGenerator() {
  var array = [1, 2];

  while (array.length) {
    yield array.shift();
  }
}

var generator = myGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: undefined, done: true }

Считать

Оба Итераторы и Генераторы Позвольте нам построить наши собственные намерения.

Разница в явном (то есть итератор) против неявного (I.e. Generator) управления государством.

Объект это ИТЕРИТЕЛЬНО Если он определяет его итерационное поведение Отказ Это означает, что объект должен иметь свойство [Символ .-ТРЕТИКА] определяется и назначен итерационным поведением.

ИТЕРИТЕЛЬНО имеет возможность повторять свои ценности через для ... петля.

для …

А для ... Заявление создает цикл, способный итерацию по поводу передовых объектов. Заявление начинается, вызывая пользовательский [Symbal.iterator] () Способ на сборке, который возвращает новый объект итератор.

Петли итерат, позвонив Далее () Метод на объекте итератора. Этот метод называется до тех пор, пока итератор не возвращает объект {Готово: правда} Отказ

var iterable = {
  [Symbol.iterator]: myGenerator
};

for (let item of iterable) {
  console.log(item);
  // 1 2
}

Тем не менее, текущий javaScript ITerator и генератор работает только для синхронных источников данных.

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

var iterable = {
  [Symbol.iterator]: function* generatorWithPromise() {
    // define an array of async data
    const promises = [Promise.resolve(1), Promise.resolve(2)];

    while (promises.length) {
      yield promises.shift();
    }
  }
};

for (item of iterable) {
  item.then(console.log);
}
console.log("done");
// done <- it should be the last to be printed
// 1
// 2

Это потому, что итератор является последовательным оператором данных. Это позволяет итерацию по поводу сбора в синхронном виде.

Интерфейс Далее () Возвращает кортеж {Значение, сделано} и значения ценность и сделано Необходимо известно в момент возвращения итератора. Поэтому Итератор наиболее подходит для синхронных источников данных.

Итератор не работает с какими-либо асинхронными источниками данных.

И итератор обещаний недостаточно. Это позволит ценность быть асинхронной, но не ценностью сделано Отказ

Мы можем сделать ценность Async, но не Статус Отказ

Вот где приходят асинхронистые итераторы.

giphy.gif.gif.

Но до этого, быстрое повторение .

Async Function

Функция Async содержит кусок с ждать выражение. ждать Выражение приостанавливает выполнение функции до тех пор, пока не разрешится пройденное обещание. После разрешения функция возобновляет его выполнение.

(async function async() {
  var one = await Promise.resolve(1);
  var two = await Promise.resolve(2);
  console.log(one, two); // 1 2
})();

Вернуться к асинхронные итераторы .

Асинхронистые итераторы похожи на итераторы, но на этот раз Далее () возвращает обещание. Это обещание решает с кортеж {Значение, сделано} Отказ

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

function asyncIterator() {
  const array = [1, 2];
  return {
    next: function() {
      if (array.length) {
        return Promise.resolve({
          value: array.shift(),
          done: false
        });
      } else {
        return Promise.resolve({
          done: true
        });
      }
    }
  };
}

var iterator = asyncIterator();

(async function() {
    await iterator.next().then(console.log); // { value: 1, done: false }
    await iterator.next().then(console.log); // { value: 2, done: false }
    await iterator.next().then(console.log); // { done: true }
})();

Как итераторы введены [Символ .-ТРЕТИКА] Чтобы получить итератор от объекта, async итераторы вводят [Symbol.asynciterator] Отказ Это позволяет нам настроить объект как асинхронный итератор.

Концепция асинхронизатора – это концепция Очередь запросов Отказ Поскольку метод ITERATOR может быть вызван до решения предыдущих запросов, она должна быть очередна внутри.

для ожидания

С async итераторами приходит утверждение для ожидания , который итерации по поводу асинхронизации источника данных.

var asyncIterable = {
  [Symbol.asyncIterator]: asyncIterator
};

(async function() {
  for await (const item of asyncIterable) {
    console.log(item);
    // 1 2
  }
})();

Что касается итераторов, для ожидания Цикл начинается, создавая источник данных через [Symbol.asynciterator] () Отказ За каждый раз Далее () называется, для ожидания Неявно ждут обещания разрешить. Это обещание возвращается методом итератора.

Async Generator возвращает обещание с кортежом {Значение, сделано} вместо непосредственно возвращения {Значение, сделано} Отказ Это позволяет генератору работать над асинхронным источником данных.

ждать выражения и для ожидания разрешены для асинхронизации генераторов.

доходность * Заявление поддерживает делегацию asynctibles.

var asyncIterable = {
  [Symbol.asyncIterator]: async function* asyncGenerator() {
    var array = [Promise.resolve(1), Promise.resolve(2)];

    while (array.length) {
      // it waits for the promise to resolve
      // before yield the value
      yield await array.shift();
    }
  }
};

(async function() {
  // it waits for each item to resolve
  // before moving to the next()
  for await (const item of asyncIterable) {
    console.log(item);
    // 1 2
  }
})();
giphy.gif.gif.

Интерфейс итераторов, привезенный ECMAScript 2015, предназначен для повторения последовательных источников данных.

Объект iTerator имеет свойство Далее () С возвратами свойства {Значение, сделано} Отказ Недвижимость ценность Содержит следующее значение в коллекции. Что касается сделано , что содержит логическое значение, указывающее, закончилась ли итерация или нет.

Так как оба значения ценность и сделано Необходимо известно в момент возврата метода итератора, итераторы подходят только для итератора над синхронными источниками данных.

Однако многие источники данных являются асинхронными. Примерами являются доступом ввода/вывода и извлечение. К этим асинхронным источникам данных итераторы не применимы.

Для этого JavaScript представляет интерфейс Asynciterator.

Asynciterator очень похож на итератор, за исключением того, что Далее () Собственность возвращает обещание с кортежом {Значение, сделано} вместо прямого значения {Значение, сделано} Отказ

const { value, done } = syncIterator.next();

asyncIterator.next().then(({ value, done }) => /* ... */);

Чтобы позволить построить настройку ASYNCITRALY, он представляет новый символ Symbol.asynciterator Отказ Объект может стать асинмитером, добавив это свойство и внедряя его асинхронное поведение итератора.

const asyncIterable = {
    [Symbol.asyncIterator]: /* asyncIterator */
};

AsynCiterable ввести вариацию для ИТРАЦИЯ ОТВЕТСТВЕННОСТЬ, в основном для ожидания Отказ Это утверждение может произойти итерации по асинкому счетным объектам.

for await (const line of readLines(filePath)) {
  console.log(line);
}

Функция генератора Async позволяет использовать источники данных Async без беспокойства о управлении состоянием итератора.

Что касается асинхронизации итераторов, он возвращает обещание со значением {Значение, сделано} и ждать выражение и для ожидания Заявления допускаются. доходность Заявление о поддержке делегации в asynctibles.