小demo见Generator函数大姿势

时间:2021-1-8 作者:admin

1. 小demo

var fetch = require('node-fetch');

function* gen(){
  var url = 'https://api.github.com/users/github';
  var result = yield fetch(url);
  console.log(result.bio);
}

上面代码中,Generator函数封装了一个异步操作,该操作先读取一个远程接口,然后从JSON格式的数据解析信息。这段代码非常像同步操作,除了加上了yield命令。

var g = gen();
var result = g.next();

result.value.then(function(data){
  return data.json();
}).then(function(data){
  g.next(data);
});

上面代码中,首先执行Generator函数,获取遍历器对象,然后使用next方法(第二行),执行异步任务的第一阶段。由于 Fetch模块返回的是一个 Promise 对象,因此要用then方法调用下一个next方法。

2. 几个疑点

  • thenreturn data.json();后为啥还能接着下一个then
  • var result = yield fetch(url);result是如何获得的?g.next(data);的作用是什么?

2.1 在thenreturn data.json();后为啥还能接着下一个then

因为then总是返回Promise,xxx.then(a => a) 的效果实际上是 return new Promise(resolve => resolve(a)),这个过程由引擎隐式完成的

2.2 var result = yield fetch(url);result是如何获得的?g.next(data);的作用是什么?

var g = gen();var result = g.next();执行g.next()后,只是执行了fetch(url),并没有把返回值赋值给result

function* gen(x){
     var y = yield x + 2;
      console.log(y);
      return y;
}
var a = gen(1);
a.next();

返回值是{value: 3, done: false},每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。

并没有打印console.log(y);,因为程序碰到yield后就暂停执行了,所以不会赋值给y,所以var y = yield x + 2;不会执行

g.next(2) // { value: 2, done: true }

第二个next方法带有参数2,这个参数可以传入Generator函数,作为上个阶段异步任务的返回结果,被函数体内的变量 y 接收。因此,这一步的 value 属性,返回的就是2(变量 y 的值)。

3. 总结

  • 调用 Generator 函数,会返回一个内部指针(即遍历器 )g
  • Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象
  • 调用指针 g 的 next 方法,会移动内部指针
  • 每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。
  • 程序遇到yield命令就暂停,等到执行权返回,再从暂停的地方继续往后执行
  • next方法返回值的value属性,是Generator函数向外输出数据
  • next 方法还可以接受参数,这是向Generator函数体内输入数据

4. 后续思考——Generator 函数的自动执行

总不能手动的一步一步的调用next来执行Generator,tj大神的co解决了这个问题

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。