跳轉到內容

JavaScript/生成器

來自華夏公益教科書



術語“生成器”指的是一種用於生成一系列“任何事物”的技術:數字、字串、資料庫查詢行、陣列元素、DOM 樹節點等。

它用於透過將資料分成小塊來避免任何記憶體超載。

要使用它們,您必須首先定義一個生成器函式[1]。此類函式用一個星號 * 表示,它直接位於關鍵字 function 後面,例如:function* myGenerator(){...}

當呼叫時,該函式不會立即執行。它只會在遇到第一個 yield 語句 **之前** 執行,並返回一個“生成器物件”。這個“生成器物件”提供了一個 next 方法。一次又一次地呼叫 next 會按順序返回序列元素。這些元素是由生成器函式中遇到的每個 yield 產生的。

  • 該指令碼生成一個包含 4 個整數的序列。
function* fourInts() {
  let int = 0;
  while (int < 4) {
    yield int;  // each .next() receives the current value of 'int'
    int++;
  }
}

const gen = fourInts();   // creation
alert(gen.next().value);  // 0
alert(gen.next().value);  // 1
alert(gen.next().value);  // 2
alert(gen.next().value);  // 3
alert(gen.next().value);  // undefined
  • 每次 next() 呼叫不僅返回一個 value;還有一個布林值 done。因此,您可以在迴圈中呼叫生成器。
function* fourInts() {
  let int = 0;
  while (int < 4) {
    yield int;
    int++;
  }
}

const gen = fourInts();   // creation
do {
  const tmp = gen.next();
  if (tmp.done) {
    break;
  } else {
    alert(tmp.value);  // 0, 1, 2, 3
  }
} while (true)
  • 從陣列、資料庫請求或樹遍歷中生成。
function* arrayElements() {
  // for simplicity, we use an array; database queries or tree traversals
  // are more realistic.
  const myArray = ["yellow", "green", "blue"];
  for (const elem of myArray) {
    yield elem;
  }
}

const sequence = arrayElements();   // creation
do {
  const tmp = sequence.next();
  if (tmp.done) {
    break;
  } else {
    alert(tmp.value);  // "yellow", "green", "blue"
  }
} while (true)
  • 建立所有偶數的無限序列。
function* evenNumbers() {
  for (let i = 0; true; i = i + 2) {
    yield i;
  }
}

const sequence = evenNumbers();   // creation
let i = 0;
while (i < 20) {
  i = sequence.next().value;
  alert(i);  // 0, 2, 4, ...
}

生成器函式可以接收引數。在本例中,'pageSize' 定義了要返回的陣列元素的數量。

function* pagination(arr, pageSize) {
  for (let i = 0; i < arr.length; i = i + pageSize) {
    yield arr.slice(i, i + pageSize);
  }
}

const arr = [1, 2, 3, 4, 5, 6, 7]
const page = pagination(arr, 3);

alert (page.next().value);   // { value: [1, 2, 3], done: false }
alert (page.next().value);   // { value: [4, 5, 6], done: false }
alert (page.next().value);   // { value: [7], done: false }
alert (page.next().value);   // { value: undefined, done: true }

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書