lxinr/interview-question

2021/02/08 - 生成器(Generator)的理解

lxinr opened this issue · 0 comments

lxinr commented

生成器对象是由一个generator function返回的,并且它符合可迭代协议和迭代器协议

语法:

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

let g = gen();
  • 调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器 ( iterator )对象
  • 生成器函数在执行时能暂停,后面又能从暂停处继续执行
  • 只有在调用该函数的next()方法后,其内的语句才会执行,到出现yield的位置为止,yield后紧跟迭代器需返回的值
  • next()方法返回一个对象,这个对象包含两个属性:valuedonevalue属性表示本次yield表达式的返回值,done属性为布尔类型,表示生成器后续是否还有yield语句,即生成器函数是否已经执行完毕并返回
  • 调用next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量,假如上一条执行的语句没有左边变量,则传参无效
生成器可以传入参数
function* Van(arr = []) {
  for(const v of arr) {
    yield v
  }
}

const van = Van([3, 5, 8, 10])

console.log(van.next().value) // 3
console.log(van.next().value) // 5
console.log(van.next().value) // 8
console.log(van.next().value) // 10
生成器函数不能当作构造函数使用
function* Van() {
  yield 2;
}
const van = new Van() // Uncaught TypeError: Van is not a constructor
generator.throw

用于向生成器抛出一个错误

function* gen() {
  while(true) {
    try {
       yield 42;
    } catch(e) {
      console.log("Error caught!");
    }
  }
}

var g = gen();
g.next(); // { value: 42, done: false }
g.throw(new Error("Something went wrong")); // "Error caught!"