如何仅在 Promise.all() 循环完成后与使用 javascript 的 setTimeOut() 一起执行 writeFileSync()?

How to execute the writeFileSync() only after the Promise.all() loop completion along with setTimeOut() using javascript?

我正在读取 .txt 文件数据并调用 第三方 api 以使用 .txt 文件数据作为参数连续获取更多数据。为此,我是 运行 一个 await Promise.all()map() 循环,使用 setTimeOut() 延迟 2 秒的功能,以便第 3 方 API 获得延迟时间并避免捕获错误。

之后我appending/pushing它到一个json对象数组。之后将整个 JSON.stringify(data) 写入 .json 文件。 我想要按顺序排列的一切。但不幸的是,在调试时,我看到 writeFileSync 甚至在我不想要的循环完成之前就被执行了。

这是我正在尝试的代码:

const writeFile = async (obj) => {
  const json = JSON.stringify(obj);
  fs.writeFileSync('/home/deb/Downloads/Twitty-Bird/src/utils/output.json', json, 'utf8')
  return 'completed';
}

export const convertToJSONFile = async () => {
  try {
    let obj = {
      table: []
    };
    const data = fs.readFileSync('/home/deb/Downloads/Twitty-Bird/src/utils/sample.txt', 'utf8');
    if (!data) throw err;
    let splitted = data.toString().split("\n");
    let interval = 2000;
    await Promise.all(splitted.map(async (word, index) => {
      setTimeout(async function () {
        let wordMeaningDetails = await axios({
        method: 'GET',
        url: `https://api.dictionaryapi.dev/api/v2/entries/en/${word}`
        })
        wordMeaningDetails = wordMeaningDetails.data[0].meanings[0].definitions[0]
        obj.table.push({
          word: word, definition: wordMeaningDetails.definition, example: wordMeaningDetails.example
        });
      }, interval);
    }))

    const res = await writeFile(obj);
    console.log(res);
  }
  catch (err) {
    console.log("Error = ", err);
    //convertToJSONFile();
  }
}

convertToJSONFile();

我想要的是通俗易懂的顺序:

  1. 首先读取所有数据并使用fs.readFileSync
  2. 分割成数组
  3. 用 axios 一个一个地执行 3rd party api 并将所有数据附加到对象 obj = {}
  4. 然后最后将 json 数据写入 .json 文件并将其保存在根文件夹中。

更新: 我现在正在使用这个更新的代码:

const promiseResponse = await Promise.all(splitted.map(async (word, index) => new Promise((resolve) => {
  setTimeout(async function () {
    let wordMeaningDetails = await findMeaning(word);
    wordMeaningDetails = wordMeaningDetails.data[0].meanings[0].definitions[0]
    obj.table.push({
      word: word, definition: wordMeaningDetails.definition, example: wordMeaningDetails.example
    });
    console.log(word);
    resolve(); // resolve the promise to mark it as "done"
  }, 1000 * index)
})
))

const res = await writeFile(obj);
console.log(res);

所以在执行整个拆分数组并解决承诺后,它会抛出以下错误而不是执行 res = await writeFile(obj). 我不知道为什么会这样。

aa
aardvark
aargh
aback
abacus
abandon
abandoned
abandoning
abandonment
abandons
(node:78808) UnhandledPromiseRejectionWarning: Error: Request failed with status code 404
    at createError (/home/vikas/Downloads/Twitty Bird/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/home/vikas/Downloads/Twitty Bird/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/home/vikas/Downloads/Twitty Bird/node_modules/axios/lib/adapters/http.js:293:11)
    at IncomingMessage.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1334:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)
(node:78808) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:78808) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

您需要 return 映射函数中的 Promise。见下文:

await Promise.all(splitted.map(async (word, index) => ...)));
// You need to return a promise not a anonymous function because the function
// will resolve instantely and is not waiting for your timeout

(async () => {

  await Promise.all([1, 2, 3].map((word, index) => new Promise((resolve) => {
    setTimeout(async function() {
      console.log(word);
      // do your api stuff
      resolve(); // resolve the promise to mark it as "done"
    }, 1000 * index)
  })))
  console.log("done!")

})();