Можем ли мы передать параметры в генератор, когда мы итерируем его через for..of? - PullRequest
0 голосов
/ 13 января 2019

Я думаю о сценарии создания очереди на обещание:

//Let's assume that promises is an array of promises
var promiseQueue = [];
for (var promise of promises) {
    if (promiseQueue.length) promiseQueue[promiseQueue.length - 1].then(promise);
    promiseQueue.push(promise);
}

Я думаю о реализации function под названием resolver:

function *resolve() {
    var promise;
    while (promise = yield) Promise.resolve(promise);
}

и затем повторяем это:

var promiseGenerator = resolve();

Проблема заключается в том, что здесь будет отвечать за фактическую итерацию:

for (var r of promiseGenerator) {

}

В приведенном выше коде генератор будет успешно повторен, но, к сожалению, я не знаю, как успешно передать параметр этому генератору при итерации for..of.

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

for (var p in promiseQueue) promiseGenerator.next(promiseQueue[p]);

Мне особенно интересно узнать, могу ли я передать параметры генератору при выполнении цикла for..of.

EDIT

Проблема, поднятая amn, заключается в том, что в примере, на котором он / она фокусировался, всегда будет undefined. Это верно, если мы передаем undefined на next(), но не верно, если мы передаем что-то еще. Проблема, которую я поднял, состоит в том, что цикл for..of не позволяет нам передавать что-либо в yield, что является конкретным вопросом, и этот пример является простой иллюстрацией проблемы, показывающей, что обещания, которые мы будем выполнять Create никогда не будет создан в цикле for..of. Однако для объектов Iterable есть жизнь вне области циклов for..of, и мы можем передать определенные значения в yield. Пример с критичным фрагментом кода может выглядеть так:

function *resolve() {
    var promise;
    while (promise = yield) Promise.resolve(promise);
}

var responses = [];
var f = resolve();
var temp;
for (var i = 10; !(temp = f.next(i)).done; i--) responses.push(temp);

Как мы видим выше, yield выше нельзя считать ab ovo равным undefined. И, конечно, мы можем передать некоторые пользовательские объекты, такие как

Promise.resolve({ 
  then: function(onFulfill, onReject) { onFulfill('fulfilled!'); }
});

или даже обещания, которые еще не были выполнены. Цель этого примера состояла в том, чтобы показать, что мы не можем передать значения в yield с помощью цикла for..of, что, по моему мнению, является пробелом в функциональности.

1 Ответ

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

Нет, невозможно передать аргументы next.

function* generateItems() { /* ... */ }
for (var item of generateItems()) {
   console.log(item);
}

это в основном сокращение от

function* generateItems() { /* ... */ }
var iterator = generateItems()[Symbol.iterator]();
do {
  const result = iterator.next();
  if (result.done) break;
  const item = result.value;

  console.log(item);
} while (true);

за исключением нескольких отсутствующих try/catch упаковщиков. Вы можете видеть в спецификации здесь , что он вызывает .next без аргументов:

Пусть nextResult будет? Вызов (iteratorRecord. [[NextMethod]], iteratorRecord. [[Iterator]], «»).

, например

iterator.next.apply(iterator, []);

вызов next() с пустым массивом аргументов.

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