如何在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 相关文章推荐
javascript字典探测用户名工具
Oct 05 Javascript
JS无法捕获滚动条上的mouse up事件的原因猜想
Mar 21 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
Jul 25 Javascript
浅析javascript 定时器
Dec 23 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
Feb 13 Javascript
js实现正则匹配中文标点符号的方法
Dec 23 Javascript
js移动焦点到最后位置的简单方法
Nov 25 Javascript
浅谈js数组和splice的用法
Dec 04 Javascript
Node.js的Mongodb使用实例
Dec 30 Javascript
微信小程序 数据遍历的实现
Apr 05 Javascript
js is_valid_filename验证文件名的函数
Jul 19 Javascript
layerUI下的绑定事件实例代码
Aug 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中的一个中文字符串截取函数
2007/02/14 PHP
php中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
2010/12/19 PHP
destoon整合ucenter后注册页面不跳转的解决方法
2014/06/21 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
Flash对联广告的关闭按钮讨论
2007/01/30 Javascript
XENON基于JSON变种
2010/07/27 Javascript
jquery的extend和fn.extend的使用说明
2011/01/09 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
2013/05/08 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
js拖拽一些常见的思路方法整理
2014/03/19 Javascript
fullpage.js全屏滚动插件使用实例
2016/09/06 Javascript
D3.js实现饼状图的方法详解
2016/09/21 Javascript
AngularJS中$http使用的简单介绍
2017/03/17 Javascript
vue-resource 拦截器(interceptor)的使用详解
2017/07/04 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
2017/11/21 Javascript
Vuejs开发环境搭建及热更新【推荐】
2018/09/07 Javascript
vue2.0 + ele的循环表单及验证字段方法
2018/09/18 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
操作Windows注册表的简单的Python程序制作教程
2015/04/07 Python
python-docx修改已存在的Word文档的表格的字体格式方法
2018/05/08 Python
Python装饰器的执行过程实例分析
2018/06/04 Python
python scatter散点图用循环分类法加图例
2019/03/19 Python
django云端留言板实例详解
2019/07/22 Python
详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
2019/08/23 Python
决策树剪枝算法的python实现方法详解
2019/09/18 Python
浅析Python面向对象编程
2020/07/10 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
纯CSS3实现扇形动画菜单(简化版)实例源码
2017/01/17 HTML / CSS
在html页面中取得session中的值的方法
2020/08/11 HTML / CSS
铁路安全事故反思
2014/04/26 职场文书
火锅店的活动方案
2014/08/15 职场文书
节能环保家庭事迹材料
2014/08/27 职场文书
老兵退伍标语
2014/10/07 职场文书
网络营销实训总结
2015/08/03 职场文书
基于PyQT5制作一个桌面摸鱼工具
2022/02/15 Python
MySQL数据库如何查看表占用空间大小
2022/06/10 MySQL