如何一个接一个地完成这些功能?

时间:2019-12-28 20:01:29

标签: javascript node.js asynchronous

我有以下功能,该功能未按我想要的顺序执行。

实际上,在函数内部的循环执行之前,回调中的console.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()

4 个答案:

答案 0 :(得分:2)

使用更新的fs.promises接口进行编码非常简单,因此您可以await readdir()输出:

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接口,可以await的结果readdir()
  2. getFiles()更改为async,以便我们可以使用await,这样它会返回一个诺言,当所有异步工作完成后,诺言就会解决。
  3. data移入函数(从getFiles()解析并传递给createDatabase())中,而不是作为多个函数共享的顶级变量。
  4. 跟踪致电run()的完成情况和错误
  5. 实际上是在getFiles()之后用括号括起run()

答案 1 :(得分:1)

以下代码段将首先完全运行getFiles函数,然后运行createDatabase函数。对于使用异步/等待,函数需要返回一个Promise(请参阅Promise here)。

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。仅在返回承诺时使用等待。您可以阅读有关异步/等待here的信息。

答案 2 :(得分:-1)

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

Using async/await with a forEach loop

答案 3 :(得分:-1)

我不太确定您到底想做什么,但问题似乎出在您的运行功能上。您没有在运行中调用getFiles函数。您只需要提及函数名称即可。还需要包装getFiles以保证它应该是

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