介绍
ES2017(或称为ES8)中引入了生成器函数(Generator Function),它可以让开发者更加方便地处理异步任务。生成器函数是一种可以通过不断暂停和恢复执行来取得多个值的函数。在调用生成器函数时,它会返回一个 迭代器(Iterator) 对象,通过 next
方法调用迭代器的下一个生成值。
基本语法
生成器函数的语法类似于普通函数,只是在函数名前加上一个星号 *
来表示它是一个生成器函数。一般的函数执行完毕之后就直接返回, 与此不同,生成器函数执行完后会暂停执行,等待下一次调用。
下面是一个简单的生成器函数的例子:
// javascriptcn.com 代码示例 function* myGenerator() { yield 'hello'; yield 'world'; yield '!'; } const gen = myGenerator(); console.log(gen.next()); // { value: 'hello', done: false } console.log(gen.next()); // { value: 'world', done: false } console.log(gen.next()); // { value: '!', done: false } console.log(gen.next()); // { value: undefined, done: true }
上面的代码中,使用 function*
定义了一个生成器函数 myGenerator
,该函数中包含三个 yield
关键字,表示生成了三个值。在 const gen = myGenerator();
这一行代码中,生成了一个新的迭代器对象,然后依次调用 next()
方法,每次返回一个生成值,直到生成器函数执行完毕,done
属性才会变为 true
,不再有新的值被生成。
应用场景
生成器函数最大的作用是可以让开发者更方便地处理异步任务,例如实现异步的读取:
// javascriptcn.com 代码示例 function* readFile() { const data = yield fetch(url); // 等待获取数据 console.log(data); } const gen = readFile(); const result = gen.next(); // 执行到第一个 yield,获取到 fetch 返回的 promise 对象 result.value.then(data => { gen.next(data); // 将异步读取到的数据传入生成器函数 });
上面的代码中,我们定义了一个生成器函数 readFile
,该函数使用了 fetch
函数获取数据,但在获取数据之前使用了 yield
关键字暂停执行。在从 fetch
函数获取到数据后,将其通过 gen.next(data)
传入生成器函数中,继续执行下一个 yield
关键字,最终在控制台输出获取到的数据。
实战演练
下面我们以根据输入的数字输出个数的情况为例,来演示生成器函数的应用:
// javascriptcn.com 代码示例 function* countGenerator() { let count = 0; while (true) { const inputValue = yield count++; if (inputValue === 'reset') { count = 0; } } } const gen = countGenerator(); console.log(gen.next().value); // 0 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next('reset').value); // 0 console.log(gen.next().value); // 1
上面的代码中,我们定义了生成器函数 countGenerator
,该函数会不断地生成数字,直到接收到 reset
命令,数字会重新从 0 开始计数。通过不断调用 gen.next()
来获取生成值,实现了根据输入的数字输出个数的情况。
总结
通过这篇文章,我们了解了生成器函数的基本语法、应用场景和实战演练,它可以帮助开发者更方便地处理异步任务,对于提升开发效率和代码可读性有很大的帮助。在实际开发中,我们可以灵活使用生成器函数来解决问题,提高代码质量和可维护性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653cf4867d4982a6eb6e20d2