整个foreach完成后需要一行来运行

时间:2019-06-18 11:56:55

标签: javascript node.js foreach synchronous

我正在使用foreach循环运行 A 同步代码,但是在完成整个foreach之后,我需要执行一个步骤。

我已经阅读了许多有关此的主题,但似乎似乎无法将其包裹住以了解该怎么做。
例如,这里有很多很好的信息: Using async/await with a forEach loop
我对诺言也没有经验。

const fs = require('fs')
const path = require('path')

let sourceDir = 'srcDir/'
let destDir = 'D:/path/to/destDir/'

const isDirectory = source => fs.lstatSync(source).isDirectory()
const isFile = source => fs.lstatSync(source).isFile()
const getDirectories = source => 
        fs.readdirSync(source).map(name => path.join(source, name)).filter(isDirectory)
const getFiles = source => 
        fs.readdirSync(source).map(name => path.join(source, name)).filter(isFile)
const getData_File = file => file.substr(0,3)

getDirectories(sourceDir).forEach(dir => {
    let dirName = path.basename(dir)
    let newData = []

    getFiles(dir).forEach(file => {
        setTimeout(() => {
            newData.push(getData_File(dirName))
            console.log(file)
        }, 1000)
    })

    // If this would run after the above foreach loop, it will contain all data
    // However, it is in fact being run immediately and is therefore an empty array
    console.log(newData)

})

如上面的代码中所述,我需要在文件的整个foreach完成之后为每个目录运行一次最后一行。 最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

如果您需要在这样的循环中执行异步代码,则可以考虑将异步代码包装在Promise中。您可以使用Promise.all()来获取数组中每个Promise返回的值,只需将newData设置为该值即可。如下所示:

const files = ['file1', 'file2', 'file3', 'file4', 'file5']
let newData = [];

var promises = files.map(file => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(file);
    }, 1000);
  });
});

Promise.all(promises).then(function(values) {
  newData = values;
  //Now that all the promises have resolved, we can set newData to our values arg
  console.log(newData);
});

//Expected newData to be empty here since it'll run before our async code
console.log(newData);