如何在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 相关文章推荐
jQuery使用手册之一
Mar 24 Javascript
javascript实现的像java、c#之类的sleep暂停的函数代码
Mar 04 Javascript
利用HTML5的画布Canvas实现刮刮卡效果
Sep 06 Javascript
jquery中validate与form插件提交的方式小结
Mar 26 Javascript
json定义及jquery操作json的方法
Oct 03 Javascript
浅析Ajax语法
Dec 05 Javascript
js弹性势能动画之抛物线运动实例详解
Jul 27 Javascript
JavaScript文件的同步和异步加载的实现代码
Aug 19 Javascript
解决vue-cli3 使用子目录部署问题
Jul 19 Javascript
vue的.vue文件是怎么run起来的(vue-loader)
Dec 10 Javascript
详解webpack4.x之搭建前端开发环境
Mar 28 Javascript
js实现select下拉框选择
Jan 11 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
资料注册后发信小技巧
2006/10/09 PHP
全世界最小的php网页木马一枚 附PHP木马的防范方法
2009/10/09 PHP
php文件上传表单摘自drupal的代码
2011/02/15 PHP
JS 常用校验函数
2009/03/26 Javascript
JS打开新窗口的2种方式
2013/04/18 Javascript
javascript实现json页面分页实例代码
2014/02/20 Javascript
js中函数调用的两种常用方法使用介绍
2014/07/17 Javascript
JavaScript实现select添加option
2015/07/03 Javascript
JavaScript模拟push
2016/03/06 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
2016/08/31 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
javascript 正则表达式分组、断言详解
2017/04/20 Javascript
利用JavaScript如何查询某个值是否数组内
2017/07/30 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
vue2.0移动端滑动事件vue-touch的实例代码
2018/11/27 Javascript
在React中写一个Animation组件为组件进入和离开加上动画/过度效果
2019/06/24 Javascript
jquery图片预览插件实现方法详解
2019/07/18 jQuery
Element MessageBox弹框的具体使用
2020/07/27 Javascript
jQuery-App输入框实现实时搜索
2020/11/19 jQuery
[00:14]护身甲盾
2019/03/06 DOTA
MySQLdb ImportError: libmysqlclient.so.18解决方法
2014/08/21 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
Python3实现从排序数组中删除重复项算法分析
2019/04/03 Python
详解用Python实现自动化监控远程服务器
2019/05/18 Python
Python中的类与类型示例详解
2019/07/10 Python
DJANGO-URL反向解析REVERSE实例讲解
2019/10/25 Python
Python基础之字符串操作常用函数集合
2020/02/09 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
浅谈CSS3中display属性的Flex布局的方法
2017/08/14 HTML / CSS
猫途鹰:全球领先的旅游点评社区
2017/04/07 全球购物
便利店投资创业计划书
2014/02/08 职场文书
读书伴我成长演讲稿
2014/05/07 职场文书
学习经验演讲稿
2014/05/10 职场文书
分家协议书范本
2016/03/22 职场文书
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python