🧑🎓 个人主页:《爱蹦跶的大A阿》
🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》
目录
✨ 前言
✨ 正文
一、生成器(Generator)
什么是生成器
生成器函数
next() 方法
生成器实例
生成器委托
总结
二、异步迭代和 generator
异步迭代器
创建异步迭代器
消费异步迭代器
异步生成器函数
自定义异步迭代对象
总结
✨ 结语
✨ 前言
异步编程一直是JavaScript开发的难点。我们需要合理地处理代码的异步流程,避免Callback Hell的问题。
Generator函数为我们带来了实现异步迭代的能力。通过它和高级迭代方法的配合,我们可以编写出非常优雅的异步代码。
本文将详细介绍Generator的用法,以及它如何实现自定义的异步迭代模式。这将极大提高我们处理异步操作的能力,是每个JavaScript开发者都应当掌握的技能。
✨ 正文
一、生成器(Generator)
什么是生成器
生成器(Generator)是ES6中新增的一种异步编程解决方案。
它可以让一个函数在执行过程中多次返回值。此后,我们可以通过next()
方法恢复其执行。
生成器函数
定义生成器函数需要在函数名前加星号*
:
function* generateSequence() {yield 1;yield 2;return 3;
}
生成器函数可以通过yield
关键字返回多次。
调用生成器函数返回一个生成器对象:
let generator = generateSequence();
next() 方法
必须通过next()
方法恢复生成器的执行:
generator.next(); // {value: 1, done: false}
generator.next(); // {value: 2, done: false}
generator.next(); // {value: 3, done: true}
每次next()
调用将执行生成器直至下一个yield
语句。
生成器实例
生成器常用于封装异步操作的执行流程:
function* fetch() {let result1 = yield fetchResource1();let result2 = yield fetchResource2(result1);let result3 = yield fetchResource3(result2);return result3;}let generator = fetch();
这里生成器允许我们清楚地表示每个异步操作步骤之间的关系。
生成器委托
我们可以编写一个执行器,自动迭代生成器:
function run(generator) {let result = generator.next();while (!result.done) {result = generator.next(result.value);}return result.value;
}run(fetch());
这种方式被称为生成器委托,是更便捷的使用生成器的方式。
总结
- 生成器函数可以通过yield多次返回值
- next()方法恢复生成器执行
- 用于表示异步任务的执行步骤
- 委托自动迭代生成器
生成器是一种强大的异步编程模式,值得我们深入学习。
二、异步迭代和 generator
异步迭代器
异步迭代器(Async Iterable)是允许异步迭代的对象。它符合异步迭代协议,并且可以被for await...of
循环使用。
一个异步迭代器对象必须有一个Symbol.asyncIterator
方法,该方法返回一个异步迭代器。
创建异步迭代器
我们可以通过生成器和异步函数来创建异步迭代器:
const fetch = require('node-fetch');async function* generateAsyncSequence() {let result = await fetch('/api');yield result;}let asyncIter = generateAsyncSequence();
这里generateAsyncSequence
是一个异步生成器函数,创建了一个异步迭代器。
消费异步迭代器
可以在for await...of
循环中消费异步迭代器:
for await (let item of asyncIter) {console.log(item);
}
每次循环将await
下一次yield
产生的值。
也可以通过.next()
方法手动异步迭代:
let item = await asyncIter.next();
console.log(item.value);
异步生成器函数
异步生成器函数是一个返回异步迭代器的异步函数。形式为:
async function* name([params]) {// ···yield value;// ···
}
async
关键字表示这是一个异步函数。function*
表示这是一个生成器。
自定义异步迭代对象
我们可以定义一个类的Symbol.asyncIterator
方法来使其可异步迭代:
class Reader {constructor(url) {this.url = url;}async *[Symbol.asyncIterator]() {let response = await fetch(this.url);let reader = response.body.getReader();while(true) {let {value, done} = await reader.read();if (done) break;yield value;}return reader.closed; }}
现在这个类可以用于for await...of
循环进行异步迭代。
总结
- 异步迭代器用于异步案例下的迭代
- 可以用生成器函数创建异步迭代器
for await...of
可迭代异步迭代器Symbol.asyncIterator
方法让对象可异步迭代
异步迭代器是处理异步可迭代对象的现代方式。
✨ 结语
Generator非常适合封装异步任务的执行流程。配合高级迭代方法,我们可以自定义强大的异步处理逻辑。
这为JavaScript的异步编程带来了革命性的进步。如果你之前都依靠回调函数处理异步,是时候提升技能了!
希望本文能让你对Generator和异步迭代有一个较深的理解。将它用于项目中,可以使代码的异步流程更加清晰优雅。这是你成为异步编程高手的关键一步!