如何在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 相关文章推荐
学习ExtJS Panel常用方法
Oct 07 Javascript
stream.js 一个很小、完全独立的Javascript类库
Oct 28 Javascript
基于jquery的固定表头和列头的代码
May 03 Javascript
疯狂Jquery第一天(Jquery学习笔记)
May 11 Javascript
对new functionName()定义一个函数的理解
May 22 Javascript
jquery实现在光标位置插入内容的方法
Feb 05 Javascript
简介JavaScript中valueOf()方法的使用
Jun 05 Javascript
关于Iframe父页面与子页面之间的相互调用
Nov 22 Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
Apr 26 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
Sep 10 Javascript
vue 翻页组件vue-flip-page效果
Feb 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 include,include_once,require,require_once
2008/09/05 PHP
php adodb连接mssql解决乱码问题
2009/06/12 PHP
php笔记之:初探PHPcms模块开发介绍
2013/04/26 PHP
PHP判断文章里是否有图片的简单方法
2014/07/26 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
thinkPHP5框架auth权限控制类与用法示例
2018/06/12 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
Jquery多选框互相内容交换的实例代码
2013/07/04 Javascript
javascript模拟地球旋转效果代码实例
2013/12/02 Javascript
JavaScript创建闭包的两种方式的优劣与区别分析
2015/06/22 Javascript
微信小程序 video组件详解
2016/10/25 Javascript
JS中如何实现点击a标签返回页面顶部的问题
2017/01/19 Javascript
新手vue构建单页面应用实例代码
2017/09/18 Javascript
swiper自定义分页器使用方法详解
2020/09/14 Javascript
详解React中setState回调函数
2018/06/14 Javascript
vue+element的表格实现批量删除功能示例代码
2018/08/17 Javascript
如何用Node写页面爬虫的工具集
2018/10/26 Javascript
vue路由传参三种基本方式详解
2019/12/09 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
2020/11/16 Javascript
python 二分查找和快速排序实例详解
2017/10/13 Python
PyTorch学习笔记之回归实战
2018/05/28 Python
python 将对象设置为可迭代的两种实现方法
2019/01/21 Python
python求平均数、方差、中位数的例子
2019/08/22 Python
Pygame框架实现飞机大战
2020/08/07 Python
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
Genny意大利官网:意大利高级时装品牌
2020/04/15 全球购物
户籍证明的格式
2014/01/13 职场文书
国庆宣传标语
2014/06/30 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
小学优秀班主任材料
2014/12/17 职场文书
如何用JS实现简单的数据监听
2021/05/06 Javascript
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android
python编程实现清理微信重复缓存文件
2021/11/01 Python
SpringBoot连接MySQL获取数据写后端接口的操作方法
2021/11/02 MySQL