Блог веб разработки

Блог веб-разработки статьи | видеообзоры | исходный код

Javascript генераторы

Всем привет, так что же это такое за функции генераторы спросите вы и как их использовать?!

Функция генератор чем то напоминает обычную функцию , но возвращает не одно значение, а несколько по одному. И сразу рассмотрим пример:

function* generator_function(){
    yield 1;
    yield 2;
    yield 3;
}

var generator = generator_function();
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);

Сморить в консоль и видим:

1

2

3

Теперь давайте разбираться что я здесь такого понаписал!

Во первых функция генератор определяется с помощью данного выражения function* ,во вторых для того чтобы нам вызвать функцию генератор необходимо воспользоваться методом next();, в третьих при каждом вызове функции генератора в ее теле выполняется код до ключевого слова yield, в четвертых все что находится между yield и точкой с запятой будет возвращено, в пятых для того чтобы принять, то что возвращает функция генератор мы должны в вызов функции дописать метод value;

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

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

function* generator_function(){
//Первая итерация
    yield 1; //Конец первой итерации возвращаемое значение 1
//Вторая итерация
    yield 2; //Конец второй  итерации возвращаемое значение 2
//Третья итерация
    yield 3; //Конец третьей итерации возвращаемое значение 3
}

Мы с вами вызываем функцию генератор три раза и сразу же выводим, то что она возвращает в консоль:

console.log(generator.next().value);//Первый вызов нам возвращается результат первой итерации и так далее
console.log(generator.next().value);
console.log(generator.next().value);

Мы можем также, ничего не возвращать, вывести значения в консоль через сам генератор:

function* generator_function(){
    console.log(1);
    yield;
    console.log(2);
    yield;
    console.log(3);
    yield;
}

var generator = generator_function();
generator.next();
generator.next();
generator.next();

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

В результате у нас получилось:

1

2

3

{value: undefined, done: true} или undefined , что означает что значение или сценарий четвертой итерации не определены, потому что она у нас попросту не указана в генераторе.

Теперь давайте что-нибудь скреативим чтобы посмотреть на возможности применения генераторов, рассмотрим такой пример:

function* generator_function(){

    yield 'red';

    yield 'yellow';

    yield 'blue';

    yield 'green';

    yield 'gray';

    yield 'black';

    yield 'white';

    yield false;
}

var generator = generator_function();
var interval = setInterval(function(){
    var value = generator.next().value;
    if(value === false){
        clearInterval(interval);
        return false;
    }
    console.log('backgroundBody: ',value);
    document.querySelector('body').style.background =  value;
},1000);

Как видите через каждую секунду у нас вызывается генератор и возвращает значение определенной итерации, в качестве значения возвращается название цвета которое мы подставляем в стиль фона background и выводим значение в консоль. И наконец в самом конце мы завершаем вызов нашего генератора возвращая значение false, которое удовлетворяет условию value === false, и завершает наш таймер setInterval

Так теперь поговорим о методе return(value). Выполнение функции генератора можно завершить в любой момент до того как она вернет нас все значения, вызвав метод return(), который может принимать один необязательный параметр, последнее возвращаемое значение, пример:

function* generator_function(){
    console.log(1);
    yield;
    console.log(2);
    yield;
    console.log(3);
    yield;
}

var generator = generator_function();
generator.next();
generator.next().return();
generator.next();

Результат выполнения:

1

2

Как видите метод return() завершил выполнение на второй итерации нашего генератора, то есть третий вызов функции генератора не был выполнен. Мы можем также в качестве возвращаемого значения генератора принимать , значения другого генератора через ключевое слово, yield*, пример:

function* generator_function(){
    console.log(4);
    yield;
    console.log(5);
    yield;
    console.log(6);
    yield;
}
function* generator_function2(){
    console.log(1);
    yield;
    console.log(2);
    yield;
    console.log(3);
    yield;

    yield* generator_function();
}

var generator = generator_function2();
generator.next();
generator.next();
generator.next();
generator.next();
generator.next();
generator.next();

Результат:

1

2

3

4

5

6

До сих пор мы выполняли перебор значений итерируемого объекта с помощью метода next(), что не очень то удобно. В ES6 появился новый цикл for-of предназначений для обхода значений итерируемого объекта, сейчас продемонстрирую его использование:

Берем предыдущий пример, и испоьзуем цикл for-of

function* generator_function(){
    console.log(4);
    yield;
    console.log(5);
    yield;
    console.log(6);
    yield;
}
function* generator_function2(){
    console.log(1);
    yield;
    console.log(2);
    yield;
    console.log(3);
    yield;

    yield* generator_function();
}

var generator = generator_function2();
for(var value of generator_function2());

Как видите результат у нас остался код сохранился , если мы допустим записали генератор в таком виде тогда:

function* generator_function2(){

    yield 1;

    yield 2;

    yield 3;


}

var generator = generator_function2();
for(var value of generator_function2()){
console.log(value);
}

Все очень просто, этот цикл кстати можно, использовать для перебора значений массивов, пример:

Можно перебрать одномерный массив так:

var array = [1,2,3];
for(var i in array){
console.log(array[i]);
}
С использованием цикла for-of:
var array = [1,2,3];
for(var i of array){
console.log(i);
}

Большой разницы , как таковой нет, можете перебирать как хотите.

Данная статья подошла к концу, надеюсь я смог донести до вас новую информацию и вы не раз еще ей воспользуетесь. Удачи!

Оцените статью

Еще статьи

let javascript

PHP буфер

CSS flexbox

iframe javaScript

CSS шрифты

CSS counter-increment

php null

css zoom

Комментарии

В данном разделе пока нет комментариев!

История

    НОВОСТИ

    • Опубликовал приложение под android 'Аудиокниги'. Кому интересно, переходите по ссылке