Нужна одна строка для запуска после завершения каждого foreach - PullRequest
0 голосов
/ 18 июня 2019

Я выполняю A синхронный код с циклом foreach, но мне нужно выполнить один шаг после завершения всего foreach.

Я читал много веток по этому поводу, но я просто не могу понять, что здесь делать.
Например, здесь много полезной информации: Использование async / await с циклом forEach .
У меня также нет опыта с обещаниями.

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 голосов
/ 18 июня 2019

Если вам нужно выполнить асинхронный код в цикле, подобном этому, вы можете рассмотреть обертывание асинхронного кода в 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);
...