0

Here is the code in question:

        const scriptFiles = fs.readdirSync(scriptsPath)
            .filter(file => file.endsWith(".sql"));

        for (const file of scriptFiles) {

            var data = fs.readFileSync(`${scriptsPath}/${file}`, 'utf8');
            fs.appendFile(`${scriptsPath}/Hotfix.sql`, data.toString() + "\n", (err) => {
                if (err) throw new Error(err)
                console.log('Appending ' + file + '...')
            })

            process.stdout.cursorTo(0);
        }

        console.log(`start ${scriptsPath}/Hotfix.sql`)
        exec(`start ${scriptsPath}/Hotfix.sql`)

The problem that I'm running into is that it is attempting to open/start scriptsPath/Hotfix.sql before anything has been appended to the file. For example, here is the output from the console.log()s I've added to the script:

start scriptsPath/Hotfix.sql
Appending file1.sql...    
Appending file2.sql...

is there a way I can have the script wait until the for loop has completed before attempting to execute the command?

4

2 回答 2

1

Either use .appendFileSync() and remove the (err)=> callback, or write your code as async entirely.

There is an async version of the fs API, you can access it via require('fs').promises.

In that case, you will have to use await, your code must be an async function. For an utility script that only does one thing, the benefit of doing it that way is questionable.

于 2020-10-27T16:40:27.940 回答
1

Replace the appendFile() asynchronous method with the appendFileSync() synchronous method so that code waits until the loop has completed.

const scriptFiles = fs.readdirSync(scriptsPath)
  .filter(file => file.endsWith(".sql"));

for (const file of scriptFiles) {

  var data = fs.readFileSync(`${scriptsPath}/${file}`, 'utf8');
  fs.appendFileSync(`${scriptsPath}/Hotfix.sql`, data.toString() + "\n");

  process.stdout.cursorTo(0);
}

console.log(`start ${scriptsPath}/Hotfix.sql`)
exec(`start ${scriptsPath}/Hotfix.sql`)

于 2020-10-27T17:48:40.790 回答