如何在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用get实现ajax在ie里面刷新不进入后台解决方法
Aug 12 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
Aug 30 Javascript
jquery delay()介绍及使用指南
Sep 02 Javascript
AngularJS iframe跨域打开内容时报错误的解决办法
Jan 26 Javascript
jquery图片切换实例分析
Apr 15 Javascript
jQuery对JSON数据进行排序输出的方法
Jun 24 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
Sep 16 Javascript
理解 JavaScript Scoping & Hoisting(二)
Nov 18 Javascript
AngularJS中如何使用$parse或$eval在运行时对Scope变量赋值
Jan 25 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
Oct 15 Javascript
JavaScript实现图片懒加载的方法分析
Jul 05 Javascript
mpvue微信小程序开发之实现一个弹幕评论
Nov 24 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
古巴咖啡 Cubita琥爵咖啡 独特的加勒比海风味咖啡
2021/03/06 新手入门
高亮度显示php源代码
2006/10/09 PHP
傻瓜化配置PHP环境――Appserv
2006/12/13 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
利用PHP扩展Xhprof分析项目性能实践教程
2018/09/05 PHP
做网页的一些技巧(续)
2007/02/01 Javascript
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
原生javascript实现拖动元素示例代码
2014/09/01 Javascript
JS实现的表格行鼠标点击高亮效果代码
2015/11/27 Javascript
判断是否存在子节点的实现代码
2016/05/18 Javascript
jQuery遍历json的方法(推荐)
2016/06/12 Javascript
轻松掌握JavaScript中介者模式
2016/08/26 Javascript
jQuery获取select选中的option的value值实现方法
2016/08/29 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
AngularJS实现进度条功能示例
2017/07/05 Javascript
使用vuex解决刷新页面state数据消失的问题记录
2019/05/08 Javascript
JS原型prototype和__proto__用法实例分析
2020/03/14 Javascript
js HTML DOM EventListener功能与用法实例分析
2020/04/27 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
python的id()函数解密过程
2012/12/25 Python
python改变日志(logging)存放位置的示例
2014/03/27 Python
Python中设置变量作为默认值时容易遇到的错误
2015/04/03 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
2015/05/22 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
使用Python创建简单的HTTP服务器的方法步骤
2019/04/26 Python
python lambda表达式在sort函数中的使用详解
2019/08/28 Python
python系统指定文件的查找只输出目录下所有文件及文件夹
2020/01/19 Python
Python基于requests实现模拟上传文件
2020/04/21 Python
Python 实现将某一列设置为str类型
2020/07/14 Python
解决Django响应JsonResponse返回json格式数据报错问题
2020/08/09 Python
css3 flex布局 justify-content:space-between 最后一行左对齐
2020/01/02 HTML / CSS
美国最大的珠宝首饰网上商城:Jewelry.com
2016/07/22 全球购物
天巡全球:Skyscanner Global
2017/06/20 全球购物
深入理解python多线程编程
2021/04/18 Python
SQL bool盲注和时间盲注详解
2022/07/23 SQL Server