ES6系列之Generator

发布时间:2020-08-16 14:08:02 作者:a1322674015
来源:ITPUB博客 阅读:155

一、什么是Generator 函数

1.1 语法

学习 Generator 语法,你需要了解function* 、yield、next三个基本概念。

// 声明生成器函数
function* generator() {
    // A
    yield 'foo'
    // B
}
// 获取生成器对象
let g = generator();
// 第一个 next(),首次启动生成器
g.next(); // {value: "foo", done: false}
// 唤醒被 yield 暂停的状态
g.next();
// {value: undefined, done: true}

1.2 过程分析

// 分析一个简单例子
function* helloGenerator() {
   yield "hello";
   yield "generator";
   return;
}
var h = helloGenerator();
console.log(h.next());//{ value: 'hello', done: false }
console.log(h.next());//{ value: 'generator', done: false }
console.log(h.next());//{ value: 'undefined', done: true }

经过上面的分析,yield实际就是暂缓执行的标示,每执行一次next(),相当于指针移动到下一个yield位置

ES6系列之Generator

总结一下 ,Generator函数是ES6提供的一种异步编程解决方案。通过yield标识位和next()方法调用,实现函数的分段执行

1.3 yield 表达式

yield是Generator函数的暂缓执行的标识,对于yield只能配合Generator函数使用,在普通的函数中使用会报错

Generator函数中还有一种yield*这个表达方式

function* foo(){
   yield "a";
   yield "b";
   }
   function* gen(x,y){
     yield 1;
     yield 2;
     yield* foo();
     yield 3;
   }
   var g = gen();
   console.log(g.next());//{value: 1, done: false}
   console.log(g.next());//{value: 2, done: false}
   console.log(g.next());//{value: "a", done: true}
   console.log(g.next());//{value: "b", done: true}
   console.log(g.next());//{value: "3", done: true
}

当执行yield*时,实际是遍历后面的Generator函数,等价于下面的写法:

function* foo(){
   yield "a";
   yield "b";
}
function* gen(x,y){
    yield 1;
    yield 2;
    
    for(var value of foo()){
      yield value;
    }
    
    yield 3;
}

注意:yield 后面只能适配Generator函数

二、Generator应用场景

2.1 异步操作的同步化表达

Generator函数的暂停执行的效果,意味着可以把异步操作写在yield表达式里面,等到调用next方法时再往后执行。这实际上等同于不需要写回调函数了,因为异步操作的后续操作可以放在yield表达式下面,反正要等到调用next方法时再执行。所以,Generator函数的一个重要实际意义就是用来处理异步操作,改写回调函数

function* loadUI() {
  showLoadingScreen();
  yield loadUIDataAsynchronously();
  hideLoadingScreen();
}
var loader = loadUI();
// 加载UI
loader.next()
// 卸载UI
loader.next()

上面代码中,第一次调用loadUI函数时,该函数不会执行,仅返回一个遍历器。下一次对该遍历器调用next方法,则会显示Loading界面,并且异步加载数据。等到数据加载完成,再一次使用next方法,则会隐藏Loading界面。可以看到,这种写法的好处是所有Loading界面的逻辑,都被封装在一个函数,按部就班非常清晰

function* main() {
  var result = yield request("http://some.url");
  var resp = JSON.parse(result);
    console.log(resp.value);
}
function request(url) {
  makeAjaxCall(url, function(response){
    it.next(response);
  });
}
var it = main();
it.next();

2.2 控制流管理

// 异步函数
function getDataAsync (url) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            var res = {
                url: url,
                data: Math.random()
            }
            resolve(res)
        }, 1000)
    })
}
推荐阅读:
  1. ES6中迭代器、Generator函数怎么用
  2. 详解ES6 系列之异步处理实战

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

es6 generator 系列

上一篇:SpringCloud分布式微服务b2b2c电子商务(十二)在springboot中用redis实现消息队列

下一篇:教你如何创建第一个Java应用程序,编程小白不容错过~

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》