如何在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 相关文章推荐
node.js中的fs.createWriteStream方法使用说明
Dec 17 Javascript
原生JS实现响应式瀑布流布局
Apr 02 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
Jun 05 Javascript
js如何准确获取当前页面url网址信息
Sep 13 Javascript
js简单倒计时实现代码
Apr 30 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
Jun 17 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
Aug 02 Javascript
Jquery删除css属性的简单方法
Dec 04 Javascript
vue组件 $children,$refs,$parent的使用详解
Jul 31 Javascript
集合Bootstrap自定义confirm提示效果
Sep 19 Javascript
使用elementUI实现将图片上传到本地的示例
Sep 04 Javascript
前端面试知识点目录一览
Apr 15 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实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
php foreach循环中使用引用的问题
2013/11/06 PHP
Sublime里直接运行PHP配置方法
2014/11/28 PHP
php输出xml属性的方法
2015/03/19 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
2016/03/17 PHP
form自动提交实例讲解
2017/07/10 PHP
javascript在一段文字中的光标处插入其他文字
2007/08/26 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
JS网页播放声音实现代码兼容各种浏览器
2013/09/22 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
JavaScript每天必学之数组和对象部分
2016/09/17 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
2017/11/21 Javascript
axios拦截设置和错误处理方法
2018/03/05 Javascript
基于vue.js组件实现分页效果
2018/12/29 Javascript
深入koa-bodyparser原理解析
2019/01/16 Javascript
VSCode 配置uni-app的方法
2020/07/11 Javascript
JavaScript中while循环的基础使用教程
2020/08/11 Javascript
ES11屡试不爽的新特性,你用上了几个
2020/10/21 Javascript
Python程序中设置HTTP代理
2016/11/06 Python
Python BeautifulSoup [解决方法] TypeError: list indices must be integers or slices, not str
2019/08/07 Python
Numpy 中的矩阵求逆实例
2019/08/26 Python
python树的同构学习笔记
2019/09/14 Python
Python使用多进程运行含有任意个参数的函数
2020/05/02 Python
一文详述 Python 中的 property 语法
2020/09/01 Python
美国批发供应商:Kole Imports
2019/04/10 全球购物
网上常见的一份Linux面试题(多项选择部分)
2015/02/07 面试题
软件测试笔试题
2012/10/25 面试题
应届大学生求职的自我评价
2013/11/17 职场文书
新三好学生主要事迹
2014/01/23 职场文书
优秀党支部书记事迹材料
2014/05/29 职场文书
2014房屋登记授权委托书
2014/10/13 职场文书
2014年班主任德育工作总结
2014/12/05 职场文书
TypeScript中条件类型精读与实践记录
2021/10/05 Javascript
Java 定时任务技术趋势简介
2022/05/04 Java/Android