generator怎么读,generatorconfig.xml 配置
简介

基本概念
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
跟普通函数的区别
function关键字与函数名之间有一个星号;函数体内部使用yield表达式,定义不同的内部状态。Generator函数不能跟new一起使用,会报错。
定义一个普通函数和定义一个Generator惰性函数
// 定义一个普通函数function auto(){ console.log(\’函数执行\’)}auto();//这是一个普通函数函数名字加上()执行函数内部的代码// Generator函数的*号当前函数变懒了function* auto(){//这种形式的函数叫做Generator函数//一遍情况下*是紧跟function关键词后面写的//加了*号让这个函数变懒了,即使加上函数名字启动依然没有执行内部的代码console.log(\’函数执行\’);console.log(\’函数执行\’);console.log(\’函数执行\’);}var result = auto(); function* helloWorldGenerator() { yield \’hello\’; yield \’world\’; return \’ending\’;}var hw = helloWorldGenerator();
上面代码定义了一个 Generator 函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。
调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象。
下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
function* auto(){console.log(\’函数执行\’);console.log(\’函数执行\’);console.log(\’函数执行\’);}/* [[GeneratorStatus]]: \”suspended\” GeneratorStatus:表示当前generator的当前状态 \’suspended\’:表示当前函数暂停*/var result = auto();//普通函数默认返回值是return undefined,那么result的也是undefined,//但是当前的函数加上*号在也不是undefined的了 // 那么怎么让当前的generator函数启动呢?function* auto(){console.log(\’函数执行\’);console.log(\’函数执行\’);console.log(\’函数执行\’); }var result = auto() //generator函数的返回结果就是iterator接口result.next();//必须调用next方法那能让这个惰性函数启动(继续执行)
ES6 没有规定,function关键字与函数名之间的星号,写在哪个位置。这导致下面的写法都能通过。
function * foo(x, y) { ··· }function *foo(x, y) { ··· }function* foo(x, y) { ··· }function*foo(x, y) { ··· } yield 表达式
由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。
遍历器对象的next方法的运行逻辑如下。
遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。如果该函数没有return语句,则返回的对象的value属性值为undefined。
yield表达式与return语句既有相似之处
都能返回紧跟在语句后面的那个表达式的值。
不同之处
每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能。一个函数里面,只能执行一次(或者说一个)return语句,但是可以执行多次(或者说多个)yield表达式。正常函数只能返回一个值,因为只能执行一次return;Generator 函数可以返回一系列的值,因为可以有任意多个yield。
注意:
yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。
另外,yield表达式如果用在另一个表达式之中,必须放在圆括号里面。
console.log(\’Hello\’ + yield 123); // SyntaxErrorconsole.log(\’Hello\’ + (yield 123)); // OK function* auto(){//当前generator函数是暂停的(suspended状态)generator是惰性函数yield \’我是yield断点的1\’;//yield是generator惰性函数的断点yield \’我是yield断点的2\’;yield \’我是yield断点的3\’; //只要没有碰到yield这个惰性函数执行完毕return 2;//return让这个generator函数结束,value值是你的返回结果 //done:true表示当前以及执行完毕(他会把当前return的返回值放在value里面表示当前函数执行完毕)//在当前generator函数中(惰性函数),yield关键词就是惰性函数的断点//(有yield关键词就会让这个惰性函数停止到这个断点)再次调用才就能再次执行一次惰性函数,//知道执行完这个函数为止(直到没有yield断点)//value:yield后面跟的值 done:false(没有执行完当前函数 //value:undefined(执行完当前函数) done:true(执行完当前函数)}var gen = auto();gen.next();//调用next函数才能让这个函数执行(会执行在当前函数yield断点位置) //可以理解yield是发动机执行一次就让当前的惰性函数执行一次// gen.next();// gen.next(); 与 Iterator 接口的关系
由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
Object.prototype[Symbol.iterator] = function* (){ for(let i in this){ yield this[i]; }}//————–function* iterEntries(obj) { let keys = Object.keys(obj); for (let i=0; i
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
function* f() { for(var i = 0; true; i++) { var reset = yield i; if(reset) { i = -1; } }}var g = f();g.next() // { value: 0, done: false }g.next() // { value: 1, done: false }g.next(true) // { value: 0, done: false }
这个功能有很重要的语法意义。
Generator 函数从暂停状态到恢复运行,它的上下文状态(context)是不变的。通过next方法的参数,就有办法在 Generator 函数开始运行之后,继续向函数体内部注入值。
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z);}//yield后面跟着数据他的返回结果是undefinedvar a = foo(5);//a是foo这个惰性函数的执行的结果,而foo(generator)执行的结果是一个iterator//接口当前状态是suspended暂停状态a.next() // Object{value:6, done:false}a.next() // Object{value:NaN, done:false}a.next() // Object{value:NaN, done:true}var b = foo(5);b.next() // { value:6, done:false }b.next(12) // { value:8, done:false }b.next(13) // { value:42, done:true } for…of 循环
for…of循环可以自动遍历 Generator 函数时生成的Iterator对象,且此时不再需要调用next方法。
function *foo() { yield 1; yield 2; yield 3; yield 4; yield 5; return 6;}for (let v of foo()) { console.log(v);}// 1 2 3 4 5 function* fibonacci() { let [prev, curr] = [1, 1]; while(true){ [prev, curr] = [curr, prev + curr]; yield curr; }}for (let n of fibonacci()) { if (n > 10000000) break; console.log(n);} Generator.prototype.return()
Generator 函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历 Generator 函数。
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 } yield*
如果在 Generator 函数内部,调用另一个 Generator 函数,默认情况下是没有效果的。
function* foo() { yield \’a\’; yield \’b\’;}function* bar() { yield \’x\’; foo(); yield \’y\’;}for (let v of bar()){ console.log(v);}// \”x\”// \”y\”
foo和bar都是 Generator 函数,在bar里面调用foo,是不会有效果的。
这个就需要用到yield*表达式,用来在一个 Generator 函数里面执行另一个 Generator 函数。
function* bar() { yield \’x\’; yield* foo(); yield \’y\’;}// 等同于function* bar() { yield \’x\’; yield \’a\’; yield \’b\’; yield \’y\’;}// 等同于function* bar() { yield \’x\’; for (let v of foo()) { yield v; } yield \’y\’;}for (let v of bar()){//next函数已经在for of循环里面自动的调用了 console.log(v);}// \”x\”// \”a\”// \”b\”// \”y\”
再来看一个对比的例子。
function* inner() { yield \’hello!\’;}function* outer1() { yield \’open\’; yield inner(); yield \’close\’;}var gen = outer1()gen.next().value // \”open\”gen.next().value // 返回一个遍历器对象gen.next().value // \”close\”function* outer2() { yield \’open\’ yield* inner() yield \’close\’}var gen = outer2()gen.next().value // \”open\”gen.next().value // \”hello!\”gen.next().value // \”close\”
上面例子中,outer2使用了yield*,outer1没使用。结果就是,outer1返回一个遍历器对象,outer2返回该遍历器对象的内部值。
从语法角度看,如果yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*表达式。
作为对象属性的 Generator 函数
如果一个对象的属性是 Generator 函数,可以简写成下面的形式。
let obj = { * myGeneratorMethod() { ··· }};94386339
《generator怎么读,generatorconfig.xml 配置》来自互联网同行内容,若有侵权,请联系我们删除!
科技资讯SEO上一篇 : DNF59为何突然停止直播?
下一篇 : 米米为何突然消失,直播界的新谜团?
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!