如何在一个接一个之后/完全完成后执行这些功能?



我有以下函数,它不会按照我想要的顺序执行。

回调中的控制台.log实际上在函数本身中的循环甚至执行之前就被触发了。所以总而言之,我希望函数"getFiles"在下一个"createDatabase"开始执行之前完全完成。

感谢您的帮助。 我已经对这个问题发疯了:(

const fs = require("fs")
let data = []
const getFiles = () => {
fs.readdir("./database/test/", (err, files) => {
files.forEach(file => {
require("../database/test/" + file)
data.push(Number(file.split(".")[0]))
console.log(data)
})
})
}
const createDatabase = () => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}

const run = async () => {
await getFiles
await createDatabase()
process.exitCode = 0
}
run()

使用较新的fs.promises接口进行编码相当简单,因此您可以awaitreaddir()输出:

const fsp = require('fs').promises;
const path = require('path');
const async getFiles = () => {
const root = "./database/test/";
let files = await fsp.readdir(root);
return files.map(file => {
require(path.join(root, file));
return Number(file.split(".")[0]);
});
}
const createDatabase = (data) => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}
const run = async () => {
let data = await getFiles();
createDatabase(data);
process.exitCode = 0
}
run().then(() => {
console.log("all done");
}).catch(err => {
console.log(err);
});

更改摘要:

  1. 使用 fs.promises 接口,这样我们就可以awaitreaddir()的结果。
  2. getFiles()更改为async,以便我们可以使用await,因此它会返回一个承诺,该承诺在所有异步工作完成后解析。
  3. data移动到函数中(从getFiles()解析并传递给createDatabase()(,而不是由多个函数共享的顶级变量。
  4. 跟踪调用run()的完成和错误
  5. 实际上在run()中用括号称呼getFiles().

以下代码片段将首先完全运行 getFiles 函数,然后运行 createDatabase 函数。对于使用 async/await,函数需要返回一个 promise(在此处阅读有关 promise 的信息(。

const fs = require("fs")
let data = []
const getFiles = () => {
return new Promise((resolve, reject) => {
fs.readdir("./database/test/", (err, files) => {
if (err) {
reject(err);
}
files.forEach(file => {
require("../database/test/" + file)
data.push(Number(file.split(".")[0]))
console.log(data)
})
resolve(true);
})
})
}
const createDatabase = () => {
data.sort((a, b) => {
return a-b
})
console.log(data)
// Do some other stuff
}

const run = async () => {
await getFiles();
await createDatabase();
process.exitCode = 0;
}
run()

由于 createDatabase 函数现在没有返回任何承诺,因此您可以删除它前面的 await。仅当返回承诺时才使用 Await。你可以在这里阅读关于async/await的信息。

该问题与对异步代码使用 forEach 循环有关。这个答案有更多关于这个问题的信息:

将 async/await 与 forEach 循环结合使用

我不太确定您到底想做什么,但看起来问题出在您的运行函数中。您没有在运行中调用 getFiles 函数。你关心的只是提到函数名称。还需要将getFiles包装在承诺中,它应该是

const run = async () => {
await getFiles();
await createDatabase();
process.exitCode = 0
}

最新更新