如何在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 相关文章推荐
无缝滚动改进版支持上下左右滚动(封装成函数)
Dec 04 Javascript
jQuery图片播放8款精美插件分享
Feb 17 Javascript
JS获取浏览器版本及名称实现函数
Apr 02 Javascript
如何在父窗口中得知window.open()出的子窗口关闭事件
Oct 15 Javascript
js实现的后台左侧管理菜单代码
Sep 11 Javascript
基于jQuery实现照片墙自动播放特效
Jan 12 Javascript
angularJS深拷贝详解
Mar 23 Javascript
webpack+vuex+axios 跨域请求数据的示例代码
Mar 06 Javascript
bootstrap treeview 树形菜单带复选框及级联选择功能
Jun 08 Javascript
关于node-bindings无法在Electron中使用的解决办法
Dec 18 Javascript
使用js实现一个简单的滚动条过程解析
Sep 10 Javascript
JavaScript日期库date-fn.js使用方法解析
Sep 09 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
MOTOROLA 摩托罗拉 MODEL 66-XI五灯中波收音机
2021/03/02 无线电
PHP 变量的定义方法
2010/01/26 PHP
php实现Linux服务器木马排查及加固功能
2014/12/29 PHP
php查询whois信息的方法
2015/06/08 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
js判断页面中是否有指定控件的简单实例
2014/03/04 Javascript
jquery实现图片左右切换的方法
2015/05/07 Javascript
基于jQuery实现拖拽图标到回收站并删除功能
2015/11/25 Javascript
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
微信小程序 安全包括(框架、功能模块、账户使用)详解
2017/01/16 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
使用Vue制作图片轮播组件思路详解
2018/03/21 Javascript
微信小程序封装分享与分销功能过程解析
2019/08/13 Javascript
JS三级联动代码格式实例详解
2019/12/30 Javascript
Node.js实现批量下载图片简单操作示例
2020/01/18 Javascript
vue-amap根据地址回显地图并mark的操作
2020/11/03 Javascript
原生微信小程序开发中 redux 的使用详解
2021/02/18 Javascript
在 Django/Flask 开发服务器上使用 HTTPS
2014/07/03 Python
python使用Matplotlib画饼图
2018/09/25 Python
python过滤中英文标点符号的实例代码
2019/07/15 Python
python Django的web开发实例(入门)
2019/07/31 Python
基于matplotlib xticks用法详解
2020/04/16 Python
python 实现一个图形界面的汇率计算器
2020/11/09 Python
墨西哥购物网站:Elektra
2020/01/21 全球购物
酒店公关部经理岗位职责
2013/11/24 职场文书
大学生实习证明范本
2014/01/15 职场文书
青奥会口号
2014/06/12 职场文书
公务员检讨书
2014/11/01 职场文书
红十字会救护培训简讯
2015/07/20 职场文书
奠基仪式致辞
2015/07/30 职场文书
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP