Javascript 异步读取for循环中的多个文件

Javascript 异步读取for循环中的多个文件,javascript,file,asynchronous,Javascript,File,Asynchronous,到目前为止,这是我的javascript代码: 文件是指向html文件的路径数组 我希望h3s是html文件的所有h3s标记的数组 function getH2OfFiles(files) { return new Promise((resolve, reject) => { let h3s = []; for (let i = 0; i < files.length; i++) { fs.readFile(path.join(__src, 'doc

到目前为止,这是我的javascript代码:

文件是指向html文件的路径数组

我希望h3s是html文件的所有h3s标记的数组

function getH2OfFiles(files) {

  return new Promise((resolve, reject) => {
    let h3s = [];
    for (let i = 0; i < files.length; i++) {
      fs.readFile(path.join(__src, 'documentation', files[i]), 'utf8', (err, data) => {
        if (err) throw err;
        if (data.match(/<h3>(.*)<\/h3>/)) {
          //console.log("->", { file: files[i], h3: data.match(/<h3>(.*)<\/h3>/)[1] })
          h3s.push(data.match(/<h3>(.*)<\/h3>/)[1]);
        }
      })

    }
    resolve(h3s);
  });
}
函数getH2OfFiles(文件){ 返回新承诺((解决、拒绝)=>{ 设h3s=[]; for(设i=0;i{ 如果(错误)抛出错误; if(data.match(/(.*)/){ //console.log(“->”,{file:files[i],h3:data.match(/(.*)/)[1]}) h3s.push(data.match(/(.*)/)[1]); } }) } 解决(h3s); }); }
它似乎在for循环中不起作用(因为它是异步的),但它是如何实现的呢?

您已经完成了大部分工作,您只需跟踪您得到了多少回调,然后等待解决,直到您得到所有回调。此外,如果出现问题,请使用
reject(err)
而不是
throw err

function getH2OfFiles(files) {

  return new Promise((resolve, reject) => {
    let h3s = [];
    let complete = 0;
    for (let i = 0; i < files.length; i++) {
      fs.readFile(path.join(__src, 'documentation', files[i]), 'utf8', (err, data) => {
        if (err) reject(err);                       // ***
        const match = data.match(/<h3>(.*)<\/h3>/);
        if (match) {                                // ***
          h3s.push(match[1]);
        }
        if (++complete === files.length) {          // ***
          resolve(h3s);                             // ***
        }                                           // ***
      })
    }
  });
}
这还有一个优点,
Promise.all
确保您以与原始Promise数组相同的顺序接收数组(如果重要的话)


(注意:有一些lib可以为您提供ify NodeJS api。)

Promise世界中的
for
循环的对应项是
Promise。所有
,通常与
.map
结合使用。在您的情况下,编写一个处理一个文件的函数,例如

function getH3OfFile(fileName) {
    return new Promise((resolve, reject) => {
        fs.readFile(path.join('.....', fileName), 'utf8', (err, data) => 
            err
                ? reject(err)
                : resolve(data.match(/<h3>(.*)<\/h3>/))
        );
    });
}

(以防您不知道,还有
readFileSync
)。

使用npm模块。它们为控制流提供同步迭代方法以及不同的方法,如串行、瀑布、并行等。

您需要
承诺。这里所有的
。@georg:只有当他/她承诺如果
读取文件
。可能想过滤掉
空值
s。@T.J.Crowder:当然,留作练习。
function getH3OfFile(fileName) {
    return new Promise((resolve, reject) => {
        fs.readFile(path.join('.....', fileName), 'utf8', (err, data) => 
            err
                ? reject(err)
                : resolve(data.match(/<h3>(.*)<\/h3>/))
        );
    });
}
let fileNames = [...]

Promise
   .all(fileNames.map(getH3OfFile))
   .then(h3s => ...) // h3s is an array of matches