generator函数

124 阅读2分钟

「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战」。

generator函数

generator函数的声明是在func0tion关键字后面加*来进行声明的。

function* say(){
  let a = yield 'h'
  console.log(a, 'a')
  let b = yield 'ell'
  console.log(b, 'b')
}

生成器与迭代器

generator函数也被称作为生成器,他的返回值是一个迭代器,下面的it就是称之为迭代器。

let it = say()

next

我们可以通过it来调用next()next() 方法返回一个包含属性 donevalue 的对象。该方法也可以通过接受一个参数用以向生成器传值。

let o1 = it.next() //{value:'h', done:false} //第一次的next不需要传递参数,传了也没有意义
let o2 = it.next('2') // {value:'ell', done:false}  第二次调用next我们传递的参数会把值赋给a  此时会打印 2 a   假如我们不传递参数 a的值就是undefined

let o3 = it.next() //{value:undefined, done:true} 

return

return() 方法返回给定的值并结束生成器。

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

var g = gen();

g.next();        // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next();        // { value: undefined, done: true }

throw

throw() 方法用来向生成器抛出异常。

下面的例子展示了一个简单的生成器并使用 throw方法向该生成器抛出一个异常,该异常通常可以通过 try...catch 块进行捕获.

function* gen() {
  while(true) {
    try {
       yield 88;
    } catch(e) {
      console.log("err!");
    }
  }
}

var g = gen();
g.next(); // { value: 88, done: false }
g.throw(new Error("err")); // "err!"

generator函数与co

  • 我们在使用迭代器的时候需要一次一次的调用next()方法,这很不方便,co函数的作用主要是给我们自动的去调用迭代器,我们只需要把迭代器传递给它,它会自动帮我们迭代完,不需要我们手动的去一次次迭代了。

  • co函数也有别人写好的npm包,可以去安装npm install co,我们主要来实现一下co

function co(it){
    return new Promise((resolve,reject)=>{
        // 异步迭代就采用回调函数的方式 
        function next(data){
            let { value, done } = it.next(data);
            if(done){
                return resolve(value)
            }
            Promise.resolve(value).then(next,(err)=>{
                it.throw(err);
            })
        }
        next();
    })
}