什么是 Generator?
Generator 是 ES6 新增的一种函数类型,可以看做是一个状态机,内部封装了多个状态,每次调用 Generator 函数时,可以返回一个迭代器对象,通过调用迭代器的 next 方法,可以依次遍历 Generator 中的每个状态,直到遇到 return 语句或者 Generator 函数执行结束。
Generator 的语法
Generator 函数的语法和普通函数类似,但是在函数名前面多了一个星号(*),并且函数内部使用 yield 语句来定义状态。
// javascriptcn.com 代码示例 function* generatorFunction() { yield 'state 1'; yield 'state 2'; return 'done'; } const generator = generatorFunction(); console.log(generator.next()); // { value: 'state 1', done: false } console.log(generator.next()); // { value: 'state 2', done: false } console.log(generator.next()); // { value: 'done', done: true }
Generator 的使用场景
Generator 函数可以用于异步编程,通过 yield 语句可以暂停函数执行,并返回一个 Promise 对象,等待 Promise 对象执行完毕后,再继续执行 Generator 函数的下一个状态。
// javascriptcn.com 代码示例 function* asyncGeneratorFunction() { const result = yield new Promise((resolve, reject) => { setTimeout(() => { resolve('async result'); }, 1000); }); yield result; } const asyncGenerator = asyncGeneratorFunction(); const promise = asyncGenerator.next().value; promise.then((result) => { console.log(result); // 'async result' const nextValue = asyncGenerator.next(result).value; console.log(nextValue); // 'async result' });
Generator 函数还可以用于实现类似迭代器的功能,可以通过 yield 语句依次返回一个集合中的每个元素。
// javascriptcn.com 代码示例 function* iteratorGenerator(collection) { for (let i = 0; i < collection.length; i++) { yield collection[i]; } } const iterator = iteratorGenerator([1, 2, 3]); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
实践案例
下面是一个使用 Generator 函数和 Promise 实现异步加载图片的案例,当图片加载完成后,将图片添加到 DOM 中。
// javascriptcn.com 代码示例 function* loadImage(url) { const img = new Image(); img.src = url; yield new Promise((resolve, reject) => { img.onload = () => { resolve(img); }; img.onerror = (error) => { reject(error); }; }); } function* loadImages() { const container = document.getElementById('container'); const urls = [ 'https://picsum.photos/id/237/200/300', 'https://picsum.photos/id/238/200/300', 'https://picsum.photos/id/239/200/300', ]; for (let i = 0; i < urls.length; i++) { const img = yield* loadImage(urls[i]); container.appendChild(img); } } const imagesLoader = loadImages(); function loadNextImage() { const { done } = imagesLoader.next(); if (!done) { setTimeout(loadNextImage, 1000); } } loadNextImage();
总结
Generator 函数是一种非常强大的函数类型,可以简化异步编程和迭代器的实现,同时也可以提高代码的可读性和可维护性。在实际开发中,我们可以结合 Promise、async/await 等技术,更好地利用 Generator 函数的优势,提高代码的效率和质量。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/657d1fa8d2f5e1655d7ec21e