如何在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 相关文章推荐
在网页中使用document.write时遭遇的奇怪问题
Aug 24 Javascript
js读写(删除)Cookie实例详解
Apr 17 Javascript
javascript 构造函数方式定义对象
Jan 02 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
详解基于webpack和vue.js搭建开发环境
Apr 05 Javascript
angularjs封装$http为factory的方法
May 18 Javascript
使用vue + less 实现简单换肤功能的示例
Feb 21 Javascript
vue2.5.2使用http请求获取静态json数据的实例代码
Feb 27 Javascript
js中Array对象的常用遍历方法详解
Jan 17 Javascript
使用layui 的layedit定义自己的toolbar方法
Sep 18 Javascript
js实现自动播放匀速轮播图
Feb 06 Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
Aug 04 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/05/04 PHP
PHP安全下载文件的方法
2016/04/07 PHP
PHP实现微信支付(jsapi支付)流程步骤详解
2018/03/15 PHP
thinkphp5框架路由原理与用法详解
2020/02/11 PHP
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
通过$(this)使用jQuery包装后的方法或属性
2014/05/18 Javascript
js函数参数设置默认值的一种变通实现方法
2014/05/26 Javascript
PHP+jQuery+Ajax实现多图片上传效果
2015/03/14 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
基于javascript实现句子翻牌网页版小游戏
2016/03/23 Javascript
jQuery循环遍历子节点并获取值的方法
2016/04/14 Javascript
利用python分析access日志的方法
2016/10/26 Javascript
JS实现针对给定时间的倒计时功能示例
2017/04/11 Javascript
详解vue表单验证组件 v-verify-plugin
2017/04/19 Javascript
node实现简单的反向代理服务器
2017/07/26 Javascript
关于JavaScript中forEach和each用法浅析
2017/07/27 Javascript
基于jquery.page.js实现分页效果
2018/01/01 jQuery
vue简单封装axios插件和接口的统一管理操作示例
2020/02/02 Javascript
JS轮播图的实现方法
2020/08/24 Javascript
[01:20:06]TNC vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python实现的udp协议Server和Client代码实例
2014/06/04 Python
人生苦短我用python python如何快速入门?
2018/03/12 Python
python实现蒙特卡罗方法教程
2019/01/28 Python
24式加速你的Python(小结)
2019/06/13 Python
python 实现12bit灰度图像映射到8bit显示的方法
2019/07/08 Python
Django 大文件下载实现过程解析
2019/08/01 Python
python爬取网易云音乐热歌榜实例代码
2020/08/07 Python
python爬虫scrapy基于CrawlSpider类的全站数据爬取示例解析
2021/02/20 Python
CSS3实现可翻转的hover效果
2018/05/23 HTML / CSS
西班牙拥有最佳品牌的动物商店:Animalear.com
2018/01/05 全球购物
Skechers越南官方网站:来自美国的运动休闲品牌
2021/02/22 全球购物
大学生暑期社会实践证明范本
2014/10/24 职场文书
技术入股合作协议书
2016/03/21 职场文书
2019大学毕业晚会主持词
2019/06/21 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL