JavaScript үндэс / Iterator ба Generator

Iterator ба Generator

for...of давталтаар массивын элемент бүрийг дараалан авч болдгийг та мэднэ. Гэхдээ энэ яаж ажилладгийг бодож үзсэн үү? Ард нь iterator гэсэн механизм байдаг. Iterator ба Generator нь өөрийн дараалал бүтээх, том өгөгдлийг хэсэгчлэн боловсруулах хүчирхэг хэрэгслүүд юм.

Iterator гэж юу вэ?

Iterator бол next() гэсэн методтой объект юм. next() дуудах бүрт { value, done } хэлбэрийн объект буцаана — done нь true болтол дараалал үргэлжилнэ.

javascript
function тоолуур_үүсгэх(эхлэл, төгсгөл) {
  let одоо = эхлэл;

  return {
    next() {
      if (одоо <= төгсгөл) {
        return { value: одоо++, done: false };
      }
      return { value: undefined, done: true };
    },
  };
}

const тоолуур = тоолуур_үүсгэх(1, 3);

console.log(тоолуур.next()); // { value: 1, done: false }
console.log(тоолуур.next()); // { value: 2, done: false }
console.log(тоолуур.next()); // { value: 3, done: false }
console.log(тоолуур.next()); // { value: undefined, done: true }

for...of давталт нь үнэндээ дотроо яг ийм next() дуудаж ажилладаг.

Generator функц

Generator нь iterator-г илүү хялбараар бичих арга юм. function* тэмдэглэгээг ашиглана. yield түлхүүр үг нь "одоо энэ утгыг өг, дараа нь энд зогс" гэсэн утгатай — функц зогссон газраасаа үргэлжлэн ажиллаж чадна.

javascript
function* тоо_гаргах() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = тоо_гаргах();

console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// for...of-тэй хамт ашиглах нь хамгийн хялбар
for (const тоо of тоо_гаргах()) {
  console.log(тоо); // 1, 2, 3
}

Generator-ын бодит хэрэглээ

Generator нь дуусашгүй дараалал үүсгэхэд маш тохиромжтой — бүх утгыг санах ойд нэг дор хадгалахгүйгээр хэрэгтэй үедээ л дараагийн утгыг үүсгэнэ.

javascript
function* fibonacci() {
  let [а, б] = [0, 1];
  while (true) {
    // дуусашгүй дараалал
    yield а;
    [а, б] = [б, а + б];
  }
}

const fib = fibonacci();

// зөвхөн хэрэгтэй хэдэн утгыг л авна
for (let i = 0; i < 8; i++) {
  process.stdout.write(fib.next().value + " ");
}
// 0 1 1 2 3 5 8 13
javascript
// Хуудаслалт (pagination) жишээ
function* хуудас_гаргах(өгөгдөл, хэмжээ) {
  for (let i = 0; i < өгөгдөл.length; i += хэмжээ) {
    yield өгөгдөл.slice(i, i + хэмжээ);
  }
}

const жагсаалт = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const хуудас = хуудас_гаргах(жагсаалт, 3);

console.log(хуудас.next().value); // [1, 2, 3]
console.log(хуудас.next().value); // [4, 5, 6]
console.log(хуудас.next().value); // [7, 8, 9]
console.log(хуудас.next().value); // [10]

Iterator ба Generator-ыг ойлгосноор for...of, spread operator, Array.from() зэрэг олон хэрэгсэл яаж ажилладгийг гүнзгий ойлгох болно. Эхэндээ ойлгоход хэцүү мэт санагдавч туршиж үзсэн тусам тодорхой болно — тэвчээртэй байгаарай!

Дараагийн хичээлд:

Symbol, WeakMap, WeakSet — JavaScript-ийн өвөрмөц гурван төрөл, тэдгээрийн хаана, яагаад хэрэгтэй талаар үзнэ.