Странный синтаксис yield в JavaScript - PullRequest
6 голосов
/ 11 августа 2011

Я только что посмотрел на очень интересный task.js Дэйва Германа.В его примере он имеет следующую строку:

var [foo, bar] = yield join(read("foo.json"),
                                read("bar.json")).timeout(1000);

Я знаком с генераторами, но я не понимаю, как выражение yield оценивает что-то, что может быть присвоено [foo, bar].На самом деле я бы не ожидал, что выражение будет назначено чему-либо, поскольку оно в основном то же самое, что и return.

Синтаксис yield для JS по-прежнему немного недокументирован, и я не смог найти информацию об этом.

Итак, чтобы прояснить мой вопрос: что в итоге назначается на foo и bar?

Ответы [ 2 ]

6 голосов
/ 21 августа 2011

На самом деле соответствующий параграф чуть ниже в https://developer.mozilla.org/En/New_in_JavaScript_1.7:

Как только генератор был запущен путем вызова метода next(), вы можно использовать send(), передавая определенное значение, которое будет рассматриваться как результат последнего yield. Затем генератор вернет операнд последующего yield.

Я думаю, что это уместно только в том случае, если генератор используется путем непосредственного вызова его методов, а не при циклическом переключении его значений - цикл всегда будет вызывать next() для генератора и никогда send().

В некотором смысле, выполнение генератора похоже на кооперативную многозадачность. Генератор выполняется до тех пор, пока не будет найден оператор yield. Он возвращает управление тому, кто вызвал next() или send() на генераторе. Затем вызывающая сторона продолжает выполнение до тех пор, пока не будет выполнен следующий вызов next() или send() - теперь генератор снова выполняется. Каждый раз значения могут передаваться взад и вперед.

Вот простой пример:

function gen()
{
  var [foo, bar] = yield 1;
  console.log("Generator got: " + foo + ", " + bar);
}

// This creates a generator but doesn't run it yet
var g = gen();

// Starts generator execution until a yield statement returns a value
var result = g.next()
console.log("Received from generator: " + result);

// Continue generator execution with [2, 3] being the return value
// of the yield statement. This will throw StopIteration because the
// iterator doesn't have any more yield statements.
g.send([2, 3]);
0 голосов
/ 11 августа 2011

https://developer.mozilla.org/En/New_in_JavaScript_1.7

Функция, содержащая ключевое слово yield, является генератором. Когда вы вызываете его, его формальные параметры привязываются к фактическим аргументам, но его тело фактически не оценивается. Вместо этого возвращается генератор-итератор. Каждый вызов метода next () генератора-итератора выполняет очередной проход через итерационный алгоритм. Значение каждого шага - это значение, указанное в ключевом слове yield. Думайте о yield как о генерато-итераторной версии возврата, указывающей границу между каждой итерацией алгоритма. Каждый раз, когда вы вызываете next (), код генератора возобновляется с оператора, следующего за yield.

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