2016-05-09 2 views
2

На странице Mozilla, iterators and generators есть заявление:Итератор и генератор в Javascript?

Хотя пользовательские итераторы являются полезным инструментом, их создание требует тщательного программирования в связи с необходимостью поддержания их явно внутреннего состояния. Генераторы предоставляют мощную альтернативу: они позволяют определить итерационный алгоритм, написав одну функцию , которая может поддерживать свое собственное состояние.

Относительно выше объяснения, не возможно писать итеративный алгоритм без генераторов, таких как:

Array[Symbol.iterator] = function(){ 
    return { 
     next: function(){ 
      //logic 
      return { 
       value: "", 
       done:false 
      } 
     } 
    } 
} 

Не удается получить мою голову вокруг. Может ли кто-нибудь объяснить, в чем главная причина, по которой они создали альтернативу, кажется мне не совсем по-другому.

+0

'next': функция итерации для каждой переменной в массиве. –

+0

Я рекомендую googling «синтаксический сахар». – zzzzBov

+0

@zzzzBov, в угловом2 '#' персонаже синтаксический сахар, но в его случае я так не думаю, – serkan

ответ

4

Они могут выглядеть довольно похожими на поверхности, но их можно использовать по-разному.

итераторов и итерируемые

Итераторов достаточно строго определены: они являются объектом (итераторы), который содержит (и, возможно, некоторые другие функции) в next. Каждый раз, когда функция next называется, ожидается, что она возвращает объект с двумя свойствами:

  • value: текущее значение итератора
  • done: это итератор закончил?

итератора с другой стороны, это объект, который имеет свойство с Symbol.iterator ключом (который представляет собой символ хорошо знать @@iterator). Этот ключ содержит функцию, которая при вызове возвращает новый итератор. Пример Iterable:

const list = { 
    entries: { 0: 'a', 1: 'b' }, 
    [Symbol.iterator]: function(){ 
     let counter = 0; 
     const entries = this.entries; 
     return { 
      next: function(){ 
       return { 
        value: entries[counter], 
        done: !entries.hasOwnProperty(counter++) 
       } 
      } 
     } 
    } 
}; 

Их главная цель, как следует из их названия, чтобы обеспечить интерфейс, который может быть итерированным:

for (let item of list) { console.log(item); } 
// 'a' 
// 'b' 

Генераторы

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

Хотя они могут быть итерированы (их итераторы предоставляют метод next), они могут выполнять гораздо более сложные процедуры и обеспечивать связь ввода/вывода через их метод next.

Простой генератор:

function *mygen() { 
    var myVal = yield 12; 
    return myVal * 2; 
} 

const myIt = mygen(); 

const firstGenValue = myIt.next().value; 
// Generator is paused and yields the first value 

const result = myIt.next(firstGenValue * 2).value; 

console.log(result); // 48 

Генератор делегация

Генераторы могут делегировать другому генератору:

function *mydelgen(val) { 
    yield val * 2; 
} 

function *mygen() { 
    var myVal = yield 12; 
    yield* mydelgen(myVal); // delegate to another generator 
} 

const myIt = mygen(); 
const val = myIt.next().value; 
console.log(val); 
console.log(myIt.next(val).value); 
console.log(myIt.next().value); 

Генераторы & Обещания

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

co(function *(){ 
    // resolve multiple promises in parallel 
    var a = Promise.resolve(1); 
    var b = Promise.resolve(2); 
    var c = Promise.resolve(3); 
    var res = yield [a, b, c]; 
    console.log(res); 
    // => [1, 2, 3] 
}).catch(onerror); 

В заключение

Таким образом, в заключение можно сказать, что главная цель итераторов создать интерфейс для пользовательских объектов для итерация, в то время как генераторы обеспечивают множество возможностей для синхронных и асинхронных Рабочие процессы:

  • отслеживанием состояния функции
  • делегация генератора
  • генераторы & обещает
  • CSP

т.д.

+0

* «Итераторы довольно строго определены. Они возвращают объект, который содержит следующую (и, возможно, некоторую другую) функцию. Это не так. Итераторы - это объекты, они ничего не возвращают. У них есть «следующая» функция *. Или вы имеете в виду * iterables *, а не итераторы? * «Пример итератора:« * 'list' является итерируемым в вашем примере. См. Также http://www.ecma-international.org/ecma-262/6.0/index.html#sec-iteration. –

+0

@FelixKling спасибо, эти термины меня немного смутили. Есть ли имя для функции, которая присваивается символу 'Symbol.iterator' в итерабельном? – nils

+0

Нет, что я знаю о ... –

1

Возможно ли написать алгоритм итеративного без генераторов.

Нет, это не так. Да, можно написать каждый алгоритм генератора как пользовательский итератор, но // logic в вашем коде будет намного сложнее. Акцент заявления заключается в том, что он больше не будет итеративным, он будет рекурсивным.

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

function* traverseTree(node) { 
    if (node == null) return; 
    yield* traverseTree(node.left); 
    yield node.value; 
    yield* traverseTree(node.right); 
} 

Попытка переписать его в виде пользовательского итератора. Будете ли вы застрять или сделать это, он покажет вам, в чем разница.

+0

[Это возможное решение] (http://stackoverflow.com/a/23614292/1048572) Я однажды нацарапал, но я даже не уверен, правильно ли это. – Bergi

Смежные вопросы