摘要:翻译疯狂的技术宅原文在本文中,我们将介绍两种提取循环内数据的方法内部迭代和外部迭代。它是循环和递归的组合递归调用在行。
翻译:疯狂的技术宅
原文:http://2ality.com/2018/04/ext...
在本文中,我们将介绍两种提取循环内数据的方法:内部迭代和外部迭代。
循环举个例子,假设有一个函数 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)调用 callback。
外部迭代内部迭代的替代方案是外部迭代:我们实现了一个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。但我们想要的是在该 iterable 中 yield 每个项目。这就是 yield* 的作用。
生成器有一个非常好的特性,就是处理过程能够与内部迭代一样互锁:每当 logFiles() 创建另一个 filePath 时,我们能够立即查看它,然后 logFiles() 继续。这是一种简单的协作式多任务处理,其中 yield 暂停当前任务并切换到另一个任务。
扩展阅读Chapter “Iterables and iterators” in “Exploring ES6”.
Chapter “Generators” in “Exploring ES6”.
欢迎继续阅读本专栏其它高赞文章:12个令人惊叹的CSS实验项目
世界顶级公司的前端面试都问些什么
CSS Flexbox 可视化手册
过节很无聊?还是用 JavaScript 写一个脑力小游戏吧!
从设计者的角度看 React
CSS粘性定位是怎样工作的
一步步教你用HTML5 SVG实现动画效果
程序员30岁前月薪达不到30K,该何去何从
第三方CSS安全吗?
谈谈super(props) 的重要性
本文首发微信公众号:jingchengyideng 欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/102282.html
摘要:跳过数组中的元素学会了如何按顺序从数组中提取数据。解构方法中提供了很好的解决方案。从对象中提取数据依然从最基本的开始,提取从中提取和。 本文编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58f41a06a58c240ae35bb8e6 英文连接:ES6: Destructuring — an elegant...
摘要:前言基本上,我们每天都在和中的各种语句进行着沟通,那些我们经常见面的老朋友,或者是未曾见面的新朋友,它们共同维护着的流程,让我们的程序稳步运行。 前言 基本上,我们每天都在和 JavaScript 中的各种语句进行着 沟通 ,那些我们经常见面的 老朋友,或者是未曾见面的 新朋友 ,它们共同维护着 JavaScript 的流程,让我们的程序稳步运行。那么,你是否对它们足够了解呢 如果文章...
摘要:使用构造器时,需要将模式书写成普通的字符串,因此反斜杠的使用规则与往常相同。构造器的后四个参数小时分钟秒毫秒是可选的,如果用户没有指定这些参数,则参数的值默认为。 来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目原文:Regular Expressions 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript...
摘要:查看原函数的参数注释甚至函数名的时候,只能看到装饰器的相关信息。也就是说,它是装饰器的装饰器,并且以原函数为参数,作用是保留原函数的各种信息,使得我们之后查看被装饰了的原函数的信息时,可以保持跟原函数一模一样。 貌似只能创建一个专栏,所以这篇文章只好放到JavaScript从前端到全终端里了? 原文链接:Effective Python Python 作为一门入门极易并容易上瘾的语...
摘要:所以的作用域是静态作用域,也叫词法作用域。总结是一门基于词法作用域静态作用域的语言,会沿着作用域链像气泡一样向外部寻找变量声明。又是函数作用域的语言,在中,使用和关键字后,能让变量处于块作用域中,而且不存在声明提升。 本文共 1700 字,读完只需 7 分钟 概述 变量,编程语言中我们用来模拟现实概念的工具,比方说,变量可以表示对象,数组,数字,字符。既然是工具,那么就用工具的适用范围...
阅读 3386·2021-09-22 16:00
阅读 3432·2021-09-07 10:26
阅读 2899·2019-08-30 15:55
阅读 2830·2019-08-30 13:48
阅读 1345·2019-08-30 12:58
阅读 2139·2019-08-30 11:15
阅读 919·2019-08-30 11:08
阅读 483·2019-08-29 18:41