如何在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 相关文章推荐
filemanage功能中用到的lib.js
Apr 08 Javascript
javascript 支持链式调用的异步调用框架Async.Operation
Aug 04 Javascript
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
Jun 10 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
Jun 22 Javascript
jquery序列化表单去除指定元素示例代码
Apr 10 Javascript
vue制作加载更多功能的正确打开方式
Oct 12 Javascript
angularjs之$timeout指令详解
Jun 13 Javascript
实现jquery放大镜的两种方法
Feb 22 jQuery
VuePress 静态网站生成方法步骤
Feb 14 Javascript
Vue+Express实现登录注销功能的实例代码
May 05 Javascript
简单了解JavaScript中常见的反模式
Jun 21 Javascript
layui select 禁止点击的实现方法
Sep 05 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 is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
Thinkphp+smarty+uploadify实现无刷新上传
2015/07/30 PHP
浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
2015/10/26 PHP
php微信开发接入
2016/08/27 PHP
IE 条件注释详解总结(附实例代码)
2009/08/29 Javascript
JavaScript 图片预览效果 推荐
2009/12/22 Javascript
JQuery遍历json数组的3种方法
2014/11/08 Javascript
jQuery子窗体取得父窗体元素的方法
2015/05/11 Javascript
JavaScript编写连连看小游戏
2015/07/07 Javascript
浅析JS获取url中的参数实例代码
2016/06/14 Javascript
Node.js的基本知识简单汇总
2016/09/19 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
Vue2 模板template的四种写法总结
2018/02/23 Javascript
Typescript的三种运行方式(小结)
2019/09/18 Javascript
Vue中引入svg图标的两种方式
2021/01/14 Vue.js
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
[01:02:05]LGD vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python获得文件创建时间和修改时间的方法
2015/06/30 Python
python基于pygame实现响应游戏中事件的方法(附源码)
2015/11/11 Python
Python中Proxypool库的安装与配置
2018/10/19 Python
Python遍历文件夹 处理json文件的方法
2019/01/22 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
2019/04/30 Python
python 求一个列表中所有元素的乘积实例
2019/06/11 Python
python BlockingScheduler定时任务及其他方式的实现
2019/09/19 Python
Python脚本操作Excel实现批量替换功能
2019/11/20 Python
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
西班牙英格列斯百货英国官网:El Corte Inglés英国
2017/10/30 全球购物
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
建筑学推荐信
2013/11/03 职场文书
教师节标语大全
2014/10/07 职场文书
离婚协议书范文2014
2014/10/16 职场文书
骨干教师考核评语
2014/12/31 职场文书
2015年小学英语教师工作总结
2015/05/12 职场文书
不同意离婚答辩状
2015/05/22 职场文书
vue/cli 配置动态代理无需重启服务的方法
2022/05/20 Vue.js
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL