Interators

Перебор элементов коллекции/массива/объектов

var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map(function (item) {
    return item * 2;
});
console.log(doubled);

var codes = {
  7: "Россия",
  38: "Украина",
  1: "США"
};
for (var key in codes) {
  console.log(key);
}
// Массив
var object = [1,2,3];
for (var i in object) {
    console.log(i, object[i]);
}

// Объект
var object = {a:1, b:2, c:3};
for (var i in object) {
    console.log(i, object[i]);
}

// Строка
var object = 'abc';
for (var i in object) {
    console.log(i, object[i]);
}

// Какой-то список
var object = document.querySelectorAll('div');
for (var i in object) {
    if (object.hasOwnProperty(i)) {
        console.log(i, object[i]);
    }
}

1. Обходит все свойства

2. ​for in - не дает никаких гарантий

последовательности

Interator

1. Обходит только собственные свойства

2. Можно обходить строки и массивы

 

var list = [3, 5, 7];
list.foo = 'bar';
 
for (var key in list) {
  console.log(key); // 0, 1, 2, foo
}
 
for (var value of list) {
  console.log(value); // 3, 5, 7
}

for (var value of 'User') {
  console.log(value); // U, s, e, r
}
let range = {
  from: 1,
  to: 5
}

range[Symbol.iterator] = function() {
  let current = this.from;
  let last = this.to;

  return {
    next() {
      if (current <= last) {
        return {
          done: false,
          value: current++
        };
      } else {
        return {
          done: true
        };
      }
    }

  }
};

for (let num of range) {
  alert(num); // 1, затем 2, 3, 4, 5
}

Для возможности использовать объект в for..of нужно создать в нём свойство с названием Symbol.iterator (системный символ).

 

У итератора должен быть метод next(), возвращающий объект {done: Boolean, value: any}, где value – очередное значение, а done: true в конце.

2. Позволяет задать последовательности

 

const codes = {
    7: "Россия",
    38: "Украина",
    1: "США"
};

codes[Symbol.iterator] = function() {
    const map = [7, 38, 1];
    const last = map.length;
    
    let idx = 0;
    let current = map[idx];

    return {
        next() {
            if (idx <= last) {
                current = map[idx];
                idx++;
                return {
                    done: false,
                    value: codes[current]
                };
            } else {
                return {
                    done: true
                };
            }
        }

    }
};

for (let key of codes) {
    console.log(key);
}
Пример
const getTasksInProgress = {
    cfg: {
        ...cfg,
        status: 'inProgress',
    },
    tasks: [{/*  */}, {/*  */}],
    [Symbol.iterator] = taskIterator
};

// Dashboard table 1
for (let task of getTasksInProgress) {
    console.log(key);
}
const cfg = {
    project: 'BIX',
    sprint: 12
    assingToMe: true
};
const getSubTasks = {
    cfg: {
        ...cfg,
        status: 'subTask',
    },
    tasks: [{/*  */}, {/*  */}],
    codes[Symbol.iterator] = taskIterator
};

// Dashboard table 2
for (let task of getSubTasks) {
    console.log(key);
}

Generators

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

 

Для объявления генератора используется новая синтаксическая конструкция: function* (функция со звёздочкой).

function* generateSequence() {
  const first = yield 'first yield';
  const second = yield 'second yield';
  return 'result: ' + (first + second);
}

const generator = generateSequence();

console.log(generator.next(/* don't matter */).value); // first yield
console.log(generator.next(15).value); // second yield
console.log(generator.next(10).value); // result: 25



console.log(generator.next(1000)); // {value: 1, done: false}
function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();

for(let value of generator) {
  alert(value); // 1, затем 2
}
function* generateSequence() {
  const first = yield 1;
  const second = yield 2;
  return first + second;
}

let gen = generateSequence();

console.log(gen.next()); 
console.log(gen.next()); 
console.log(gen.next().value); // ?

NaN

function* positiveNumbers() {
  return (yield) + (yield);
}
const positiveNum = positiveNumbers();
positiveNum.next();
positiveNum.next(5).value;

const positiveNumbersResult  = positiveNum.next(-10).value;
if (positiveNumbersResult < 0) {
  positiveNum.throw(new Error("the number isn't positive", positiveNumbersResult));
} else {
  console.log(positiveNumbersResult);
}

Promise

Promise

const promise = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve("result");
  }, 1000);

});

promise
    .then(fulfilled => {
      console.log(fulfilled);
    }
  )

/* ... */

.catch((err) => {
    throw new Error(err);
});

Async / Await

Пример

const generatorSum = function* (a, b) {
    const r1 = yield new Promise((res, rej) => {
        setTimeout(() => (res(a)));
    });

    const r2 = yield new Promise((res, rej) => {
        setTimeout(() => (res(b)));
    });
    
    return r1 + r2;
}

const sum = generatorSum(5, 7);

const res = sum.next().value.then((data) => {
    sum.next(data).value.then((data) => {
      console.log(sum.next(data).value);
  });
});

Простой пример

const sum = async function (a, b) {

    const r1 = await new Promise((res, rej) => {
        setTimeout(() => (res(a)));
    });

    const r2 = await new Promise((res, rej) => {
        setTimeout(() => (res(b)));
    });

    return r1 + r2;
}

sum(5, 7).then(sum => console.log(sum));

THE END

Async Await

By Sarhan Azizov

Async Await

  • 388