Generator 函数是 ES6 中引入的新的函数类型,它可以让函数在执行过程中被暂停和恢复。Generator 函数是一个状态机,封装了多个内部状态,每次调用 Generator 函数都会返回一个值,同时暂停函数执行,等待重新调用。Generator 函数的返回值是一个指向内部状态的指针对象(Iterator)。
基本用法
定义一个 Generator 函数,需要在函数名前面加上 *
。
function* genFunc() { yield 'a' yield 'b' yield 'c' } const genObj = genFunc() console.log(genObj.next()) // {value: "a", done: false} console.log(genObj.next()) // {value: "b", done: false} console.log(genObj.next()) // {value: "c", done: false} console.log(genObj.next()) // {value: undefined, done: true}
上面代码中,定义了一个 Generator 函数 genFunc
,然后使用 next()
方法逐个调用函数,可以看到每次执行函数到 yield
关键字时都会暂停并返回结果。
恢复执行
调用 next()
方法时可以传入参数,这个参数就是上一个 yield
关键字的返回值。Generator 函数会将这个参数赋值给上一个 yield
表达式,并且从这个位置继续执行。
function* star() { const a = yield 'a' const b = yield 'b' console.log(a, b) } const gen = star() console.log(gen.next()) // {value: "a", done: false} console.log(gen.next('Hello')) // {value: "b", done: false} console.log(gen.next('World')) // Hello World console.log(gen.next()) // {value: undefined, done: true}
上面代码中,第一次调用 next()
方法时没有传入参数,生成器函数执行到第一个 yield
关键字处,并返回结果 a
。第二次调用 next('Hello')
方法时将参数 "Hello"
传入,这个参数就是上一个 yield
表达式的返回值,代码继续执行到第二个 yield
关键字处,并返回结果 b
。第三次调用 next('World')
方法时将参数 "World"
传入,代码继续执行到函数结束,控制台输出 Hello World
。
使用 for...of 语句
可以使用 for...of
语句直接循环遍历 Generator 函数的每一个值。
function* colors() { yield 'Red' yield 'Green' yield 'Blue' } for (let color of colors()) { console.log(color) }
上面代码中,Generator 函数 colors()
定义了三个 yield
关键字,使用 for...of
循环逐个输出三个颜色。
使用 Generator 实现异步操作
Generator 函数可以使用 yield
关键字暂停函数的执行过程,等待其他异步操作完成后再继续执行,这样可以方便地实现异步操作。
function fetchData(url) { return new Promise(resolve => { setTimeout(() => { resolve(`Data received from ${url}`) }, 2000) }) } function* asyncFunc() { const data1 = yield fetchData('URL1') console.log(data1) const data2 = yield fetchData('URL2') console.log(data2) const data3 = yield fetchData('URL3') console.log(data3) } const asyncGen = asyncFunc() const promise = asyncGen.next().value promise.then(result1 => { asyncGen.next(result1).value.then(result2 => { asyncGen.next(result2).value.then(result3 => { asyncGen.next(result3) }) }) })
上面代码中,定义了 fetchData
函数,模拟异步请求数据并返回一个 Promise
对象。然后定义了一个 asyncFunc
Generator 函数,使用 yield
关键字分别接收三个异步操作的结果,并输出到控制台。接着定义了一个 asyncGen
对象,调用 next()
方法后可以执行到第一个异步操作。使用 Promise
对象的链式调用完成异步操作,最终输出结果。
总结
Generator 函数是一种新的函数类型,可以暂停函数执行并返回值,从而实现异步操作。Generator 函数是一种强大的工具,良好的运用可以提高代码的可读性和可维护性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b7150badd4f0e0fffae2b0