如何在JavaScript中优雅的提取循环内数据详解


Posted in Javascript onMarch 04, 2019

前言

在本文中,我们将介绍两种提取循环内数据的方法:内部迭代和外部迭代。分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

循环

举个例子,假设有一个函数 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”.

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jquery里的each使用方法详解
Dec 22 Javascript
jquery二级导航内容均分的原理及实现
Aug 13 Javascript
JS判断字符串长度的5个方法(区分中文和英文)
Mar 18 Javascript
javascript等号运算符使用详解
Apr 16 Javascript
深入剖析JavaScript中的函数currying柯里化
Apr 29 Javascript
详解springmvc 接收json对象的两种方式
Dec 06 Javascript
详谈jQuery中的一些正则匹配表达式
Mar 08 Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
Jan 29 jQuery
vue中element-ui表格缩略图悬浮放大功能的实例代码
Jun 26 Javascript
vue中使用GraphQL的实例代码
Nov 04 Javascript
Vue中rem与postcss-pxtorem的应用详解
Nov 20 Javascript
javascript实现简易的计算器
Jan 17 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
Mar 04 #Javascript
Vuex mutitons和actions初使用详解
Mar 04 #Javascript
JS重学系列之聊聊new操作符
Mar 04 #Javascript
jQuery实现的导航条点击后高亮显示功能示例
Mar 04 #jQuery
ES10 特性的完整指南小结
Mar 04 #Javascript
node.js使用express框架进行文件上传详解
Mar 03 #Javascript
微信小程序新手教程之启动页的重要性
Mar 03 #Javascript
You might like
php select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
PHP文件读写操作之文件读取方法详解
2011/01/13 PHP
PHP基础知识回顾
2012/08/16 PHP
微信接口生成带参数的二维码
2017/07/31 PHP
PHP快速排序算法实现的原理及代码详解
2019/04/03 PHP
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
如何通过javascript操作web控件的自定义属性
2013/11/25 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
JS获得多个同name 的input输入框的值的实现方法
2017/01/09 Javascript
js常用的继承--组合式继承
2017/03/06 Javascript
javascript动态创建对象的属性详解
2018/11/07 Javascript
详解Vue调用手机相机和相册以及上传
2019/05/05 Javascript
深入理解 ES6中的 Reflect用法
2020/07/18 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
2020/09/21 Javascript
python处理文本文件并生成指定格式的文件
2014/07/31 Python
Python正则表达式的使用范例详解
2014/08/08 Python
Python自动登录126邮箱的方法
2015/07/10 Python
Python3.5以上版本lxml导入etree报错的解决方案
2019/06/26 Python
python 求某条线上特定x值或y值的点坐标方法
2019/07/09 Python
Python中断多重循环的思路总结
2019/10/04 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
基于Python把网站域名解析成ip地址
2020/05/25 Python
iframe在移动端的缩放的示例代码
2018/10/12 HTML / CSS
Funko官方商店:源自美国,畅销全球搪胶收藏玩偶
2018/09/15 全球购物
经济管理专业自荐信
2013/12/30 职场文书
《台湾的蝴蝶谷》教学反思
2014/02/20 职场文书
《盘古开天地》教学反思
2014/02/28 职场文书
就业推荐表自我鉴定范文
2014/03/21 职场文书
三月法制宣传月活动总结
2014/07/03 职场文书
相亲活动方案
2014/08/26 职场文书
2015年体育教学工作总结
2015/05/20 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书
2016年万圣节活动个人总结
2016/04/05 职场文书