Generator函数是ES6新增的一种异步编程方案。
说明:Generator函数指的是一种新的语法结构,是一个遍历器对象生成器,它内部可以封装多个状态,非常适合用于异步操作。
Generator函数语法和普通的 function 函数类似,但有三个不同点:
(1)function 关键字和函数名称之间有一个星号(*)
(2)函数体内可以使用 yield [ji:ld] 语句
(3)函数调用后不会立即执行,返回的是一个遍历器对象
//一个Generator函数
function* show() { yield '百度网' yield '深圳' yield 'www.baidu.com' return 'end' }
//函数内部使用yield语法定义不同的状态,return 也可以定义一个状态,也就是说上面代码有四个状态
var y = show() // 调用此函数,并不会立即执行它其中的代码,而是返回一个遍历器对象 console.log(y.next()) // 返回一个具有value和done属性的对象 console.log(y.next()) // 有return,返回(value:end,done:true); 如果没有return, 返回(value:undefined,done:true)
yield 语法:
每一个yield语句定义不同的状态,它也是一个代码执行暂停标识。
yield语句不能在普通函数中使用,否则会报错。
调用Generator 函数可以返回一个遍历器,要想访问Generator函数中的每一个状态,需要使用遍历器对象调用next()方法
如果yield语句作为其他语句的一部分,那么必须使用小括号包裹,否则会报错
function *baidu () { // console.log("欢迎来到" + yield "百度网") // 报错 console.log("欢迎来到" + (yield "百度网")) // 正确 } let y = baidu() console.log(y.next().value) // 先返回 yield console.log(y.next().value) // 再返回 return,yield为undefined
next()方法:
next()一个主要功能,就是从暂停状态继续下一段代码的执行。
next()还有一个重要的功能,那就是可以接受一个参数,此参数作为上一个yield语句的返回值
虽然当代码执行到yield语句的时候,能够将其后面的表达式的值作为对象的value属性值,但是默认情况下yield语句是没有返回值的,或者说它的返回值是undefined
function *show() { let x = yield "你好" // 默认无返回值 console.log(x) // 输出undefined } var y = show() y.next() y.next()
注意:yield 语句的返回值和yield后面表达式的返回值是两个概念
向next中传值,注: 此值作为上一个yield的返回值
function* count (num) { let x = 2*(yield num) console.log('x = ' + x) let y = yield x*3 console.log('y = ' + y) console.log(x,y) } var g = count(5) console.log(g.next()) // {value:5,done:false},第1个next传值无意义,因为没有上一个yield // console.log(g.next()) // x = NaN {value:NaN,done:false} console.log(g.next(3)) // {value:18,done:false} console.log(g.next(3)) // {value:undefined,done:true}
注:可以通过next 进行传值,是上一个表达式中yield 的 赋值
//---------------- 异步方法实例 -------------------
setTimeout(function(){ console.log('hello') },3000) let y; var func = function(){ setTimeout(function(time){ console.log(time,'on') y.next(true) },time) } var gen = function * () { var f1 = yield func(3000) console.log('f1:', f1) var f2 = yield func(1000) console.log('f2:', f2) } y = gen() y.next() console.log('end')
.