在 JavaScript 中文雅的提取轮回内的数据

翻译:猖獗的手艺宅

原文:
http://2ality.com/2018/04/ext…

在本文中,我们将引见两种提取轮回内数据的要领:内部迭代和外部迭代。

轮回

举个例子,假设有一个函数 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 停息当前使命并切换到另一个使命。

扩大浏览

迎接继承浏览本专栏别的高赞文章:

本文首发微信民众号:jingchengyideng

迎接扫描二维码关注民众号,天天都给你推送新颖的前端手艺文章

《在 JavaScript 中文雅的提取轮回内的数据》

    原文作者:疯狂的技术宅
    原文地址: https://segmentfault.com/a/1190000018352723
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞