生成器

Frontend SELF TW
等級 45 , 課堂 1
開放

2.1 生成器的語法

JavaScript中的生成器是一種特殊的函數,可以控制代碼的執行。 它們可以暫停執行,然後稍後恢復,這讓它們成為處理非同步代碼、迭代器和其他複雜任務的強大工具。

可以使用function*(注意星號)來定義生成器。 在生成器內使用yield運算符來暫停執行並返回值。

生成器的宣告:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }
    
  

創建生成器對象

調用生成器不會立即執行其主體。相反,它返回一個生成器對象, 可以用於迭代返回值:

JavaScript
    
      const gen = generatorFunction();
    
  

2.2 使用生成器

next() 方法

next()方法用於恢復生成器的執行直到下一個yield運算符。 它返回一個具有兩個屬性的對象:

  • value: 被yield運算符傳遞的值
  • done: 布林值,表示生成器是否完成(true)或未完成(false

使用 next() 方法的範例:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }

      const gen = generatorFunction();

      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迴圈來迭代值。

迭代生成器的範例:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        yield 3;
      }

      const gen = generatorFunction();

      for (const value of gen) {
        console.log(value);
      }

      // 結果: 1
      // 結果: 2
      // 結果: 3
    
  

返回值範例

生成器可以使用return運算符返回值:

JavaScript
    
      function* generatorFunction() {
        yield 1;
        yield 2;
        return 3;
        yield 4; // 這個 yield 永遠不會執行
      }

      const gen = generatorFunction();

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

2.3 複雜使用生成器

與生成器互動

next()方法可以接受一個參數,傳遞到生成器內部。

將值傳遞到生成器的範例:

JavaScript
    
      function* generatorFunction() {
        const value1 = yield 1;
        const value2 = yield value1 + 2;
        yield value2 + 3;
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.next(10)); // { value: 12, done: false }
      console.log(gen.next(20)); // { value: 23, done: false }
      console.log(gen.next()); // { value: undefined, done: true }
    
  

錯誤處理

生成器允許使用try...catch塊來處理錯誤。

錯誤處理範例:

JavaScript
    
      function* generatorFunction() {
        try {
          yield 1;
          yield 2;
        } catch (error) {
          console.log('Error caught:', error);
        }
      }

      const gen = generatorFunction();

      console.log(gen.next()); // { value: 1, done: false }
      console.log(gen.throw(new Error('Something went wrong'))); // Error caught: Error: Something went wrong

      // { value: undefined, done: true }
    
  

創建無限序列的生成器範例

生成器可以用來創建無限的值序列:

JavaScript
    
      function* infiniteSequence() {
        let i = 0;
        while (true) {
          yield i++;
        }
      }

      const gen = infiniteSequence();

      console.log(gen.next().value); // 0
      console.log(gen.next().value); // 1
      console.log(gen.next().value); // 2

      // 以此類推
    
  

2.4 實際應用範例

範例1:迭代對象的生成器

JavaScript
    
      function* objectEntries(obj) {
        const keys = Object.keys(obj);
        for (const key of keys) {
          yield [key, obj[key]];
        }
      }

      const obj = { a: 1, b: 2, c: 3 };
      const gen = objectEntries(obj);

      for (const [key, value] of gen) {
        console.log(`${key}: ${value}`);
      }

      // 結果:
      // a: 1
      // b: 2
      // c: 3
    
  

範例2:實現簡單迭代器的生成器

JavaScript
    
      const myIterable = {
        *[Symbol.iterator]() {
          yield 1;
          yield 2;
          yield 3;
        }
      };

      for (const value of myIterable) {
        console.log(value);
      }

      // 結果: 1
      // 結果: 2
      // 結果: 3
    
  

JavaScript中的生成器是一種強大的工具,用於控制代碼的執行、創建迭代器和處理非同步操作。理解生成器的語法和使用,有助於創建更靈活和可讀的代碼,特別是在處理數據序列和非同步任務時。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION