Generator是ES6提供的一种异步编程解决方案,它的执行方式与其他函数完全不一样。
1、我们可以理解为它是一个状态机,里面封装了多个内部状态。
2、执行Generator函数会返回一个遍历器对象,所以也可以称为是遍历器生成器函数,返回的遍历器对象可以依次遍历这个Generator函数的成员和状态。
3、写法上:与普通函数不同的是,会在声明关键字后面加星号 function*;在函数内部可以使用yield表达式。这里的星号可以与function有空格,没有明确规定位置
例如:
function* helloWorld() {
yield 'hello'
yield 'world'
return 'ending'
}
let hello = helloWorld()
hello.next() // {value: 'hello', done: false}
hello.next() // {value: 'world', done: false}
hello.next() // {value: 'ending', done: false}
hello.next() // {value: undefined, done: true}
分析:
这里函数声明使用了两个yield,实际函数定义了3个状态,分别是hello\world\ending,
调用 helloWorld() 后并没有执行,而是生成一个遍历器对象,
这个对象指向对象的内部状态信息并且具有next方法,执行next方法,指针才会指向下一个状态。
由于generator函数返回的是一个遍历器对象,调用next方法才会执行遍历,因此提供了yield表达式来逐步执行遍历
每当遇到yield,遍历器就会停止并且返回yield后面的对象信息,直到遇到return或者没有return时就返回undefined来结束遍历
这里yield起到一个暂停的作用
1、yield只能用在generator函数中,否则会报错
(function (){
yield 1;
})()
// 这里会报错,因为函数不是generator函数
2、yield如果用在另一个表达式里,需要使用括号
function* demo() {
console.log('Hello' + yield); // SyntaxError
console.log('Hello' + yield 123); // SyntaxError
console.log('Hello' + (yield)); // OK
console.log('Hello' + (yield 123)); // OK
}
相同点:都会返回后面表达式的值
不同点:yield可以有多个,并且每一个值都会返回,而return就只能执行一次,返回一个值
若generator函数不使用yield表达式,则该函数可以作为暂缓执行函数使用
function* add() {
console.log('success');
}
let addFunc = add()
addFunc.next()