Generator入门及使用丨技术开发分享录

Generator入门及使用

{{ detail.nickname }}

转载 翻译 {{ formatTime(detail.create_time) }} 字数 {{ detail.content && detail.content.length }} 阅读 {{ detail.read_num }} {{ formatTag(v) }}

"## 一、简介\n\nGenerator函数是ES6引入的新型函数,用于异步编程,跟Promise对象联合使用的话会极大降低异步编程的编写难度和阅读难度。\n\n与普通函数的区别:\n\n1. function关键字与函数名之间有一个星号;\n2. 函数体内部使用yield语句,定义不同的内部状态(yield在英语里的意思就是“产出”)。\n\n## 二、简单示例\n\n### 1、yield和return\n\n```\nfunction* Foo() {\n    yield 'hello';\n    yield 'world';\n    return '!';\n}\nvar foo = Foo();\n\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\n```\n\n![clipboard.png](https://segmentfault.com/img/bVbnBe4?w=233&h=68)\n\n> 注意:generator函数不能直接使用,是通过next()方法获取yield/return的返回结果,而return可以提前终止函数。foo.return('!')方法也可终止函数。\n\n### 2、yield*\n\n#### 字符串方式\n```\nfunction* Foo() {\n    yield* 'hello';\n}\nvar foo = Foo();\n\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\n```\n\n打印结果:\n\n![clipboard.png](https://segmentfault.com/img/bVbnBfE?w=236&h=141)\n\n#### 数组方式\n\n```\nfunction* Foo() {\n    yield* ['a', 'b', 'c'];\n}\nvar foo = Foo();\n\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\nconsole.log(foo.next());\n```\n\n打印结果:\n\n![clipboard.png](https://segmentfault.com/img/bVbnBfM?w=236&h=94)\n\n### 3、与for of配合使用\n\n#### yield和return\n\n```\nfunction* Foo() {\n    yield 1;\n    yield 2;\n    return 3;\n}\nvar foo = Foo();\n\nfor(var v of foo) {\n    console.log(v);\n}\n```\n\n打印结果:\n\n![clipboard.png](https://segmentfault.com/img/bVbnBgA?w=26&h=39)\n\n从上可以看出for of不执行return值\n\n\n#### yield*\n\n```\nfunction* Foo() {\n    yield* 'hello';\n}\nvar foo = Foo();\n\nfor(var v of foo) {\n    console.log(v);\n}\n```\n\n打印结果:\n\n![clipboard.png](https://segmentfault.com/img/bVbnBgJ?w=38&h=83)\n\n### 4、throw方法\n\n```\nfunction* Foo() {\n    try {\n        yield;\n    } catch(e) {\n        console.log('内部捕获', e);\n    }\n}\n\nvar foo = Foo();\nfoo.next();\n\ntry {\n    foo.throw('a');\n    foo.throw('b');\n} catch (e) {\n    console.log('外部捕获', e);\n} \n```\n\n![clipboard.png](https://segmentfault.com/img/bVbnCOy?w=78&h=44)\n\n\n## 三、配合Promise使用\n\n```\nfunction promiseFn() {\n    new Promise(function(resolve, reject) {\n        setTimeout(function() {\n            foo.next('G');\n        }, 1000);\n    });\n}\n\nfunction* Foo() {\n    var a = yield promiseFn();\n    var b = yield promiseFn();\n    console.log(a, 111);\n    console.log(b, 222);\n}\n\nvar foo = Foo(); // foo是全局变量,挂在window上,存在变量提升,在执行到promise异步的时候,可以直接使用\nfoo.next();\n```\n\n![clipboard.png](https://segmentfault.com/img/bVbnCLb?w=50&h=40)\n\n## 四、配合ajax使用\n\ndemo.php\n\n```\n<?php\nheader('content-type: application/json');\n$a = ['name'=>'tom','age'=>rand()];\necho json_encode($a);\n```\n\ndemo.html\n\n```\nfunction ajax() {\n    $.ajax({\n        type: 'get',\n        url: 'demo.php',\n        success: function(res) {\n            foo.next(res);\n        },\n        error: function(error) {\n            foo.next(error);\n        }\n    });\n}\n\nfunction* Foo() {\n    var a = yield ajax();\n    var b = yield ajax();\n    console.log(a, 111);\n    console.log(b, 222);\n}\n\nvar foo = Foo();\nfoo.next();\n```\n\n打印结果:\n\n![clipboard.png](https://segmentfault.com/img/bVbnCMi?w=231&h=46)"
PS:写作不易,如要转裁,请标明转载出处。

如果此篇对您有帮助,可小额赞助,以兹鼓励!

猜你想看