JavaScript 中优雅提取循环内数据的两种方法

作者:橙子

时间:2026-10-22

浏览:226

本文介绍在 JavaScript 中提取循环内数据的两种方案。第一种为内部迭代,通过回调函数在循环内部处理数据;第二种为外部迭代,利用生成器实现“拉”模式,配合 yield* 进行递归处理。文章对比了两种方式的执行流程与协作机制,帮助开发者选择更优雅的代码结构。

文章目录

前言

本文将探讨从循环内部提取数据的两种实现路径:内部迭代与外部迭代。以下内容供读者参考学习,具体实现细节如下。

循环与问题背景

循环

以 logFiles() 函数为例进行说明:


const fs = require('fs');
const path = require('path');

function logFiles(dir) {
 for (const fileName of fs.readdirSync(dir)) { // (A)
 const filePath = path.resolve(dir, fileName);
 console.log(filePath);
 const stats = fs.statSync(filePath);
 if (stats.isDirectory()) {
  logFiles(filePath); // (B)
 }
 }
}
logFiles(process.argv[2]);

代码从 A 行开始的循环用于记录文件路径,该逻辑结合了 for-of 循环与递归调用(递归发生在 B 行)。

若需获取循环内的部分数据(如迭代中的文件),但不希望直接记录或处理,应如何实现?

内部迭代方案

内部迭代

提取循环数据的第一种方案是内部迭代:


const fs = require('fs');
const path = require('path');

function logFiles(dir, callback) {
 for (const fileName of fs.readdirSync(dir)) {
 const filePath = path.resolve(dir, fileName);
 callback(filePath); // (A)
 const stats = fs.statSync(filePath);
 if (stats.isDirectory()) {
  logFiles(filePath, callback);
 }
 }
}
logFiles(process.argv[2], p => console.log(p));

该方式类似于 Array 的 .forEach() 方法。在 logFiles() 内部实现循环,并对每个迭代值(A 行)执行回调函数。

外部迭代与生成器

外部迭代

内部迭代的替代方案是外部迭代:通过实现一个 iterable 对象,并利用生成器来完成此过程:


const fs = require('fs');
const path = require('path');

function* logFiles(dir) {
 for (const fileName of fs.readdirSync(dir)) {
 const filePath = path.resolve(dir, fileName);
 yield filePath;
 const stats = fs.statSync(filePath);
 if (stats.isDirectory()) {
  yield* logFiles(filePath); // (A)
 }
 }
}
for (const p of logFiles(process.argv[2])) {
 console.log(p);
}

在内部迭代中,logFiles() 主动调用外部传入的函数(即“推”数据)。而在外部迭代中,逻辑反转,由外部代码主动调用生成器(即“拉”取数据)。

需注意,在生成器中使用 yield* 进行递归调用(A 行)。若直接调用 logFiles(),它仅返回一个 iterable 对象;而使用 yield* 可将该 iterable 中的每一项逐一 yield 出来,这正是 yield* 的作用。

生成器具备一个显著优势:其处理过程可与内部迭代一样实现互锁。每当 logFiles() 生成一个新的 filePath,外部即可立即查看,随后 logFiles() 继续执行。这是一种简单的协作式多任务处理机制,其中 yield 用于暂停当前任务并切换至另一个任务。

扩展阅读

《Exploring ES6》中的“Iterables and iterators”章节。 《Exploring ES6》中的“Generators”章节。

原文链接:http://2ality.com/2018/04/extracting-loops.html

总结

以上是本文的全部内容,希望这些内容对您的学习或工作有所参考。如有疑问,欢迎留言交流,感谢支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章