//以下代码已经包含了答案中的建议,因此可以:)

在下面的脚本中,我尝试在末尾的.then调用开始运行之前完全执行'createDatabase'函数。不幸的是,我无法找到一种解决方案来实现这一目标。

在一般情况下,流程应如下:


GetFiles-完全执行
CreateDatabase-完全执行它(在等待每个.map调用完成之前,开始下一个)
在.then调用中退出脚本


非常感谢您的任何建议:)

const db = require("../database")
const fsp = require("fs").promises
const root = "./database/migrations/"

const getFiles = async () => {
  let fileNames = await fsp.readdir(root)
  return fileNames.map(fileName => Number(fileName.split(".")[0]))
}

const createDatabase = async fileNumbers => {
  fileNumbers.sort((a, b) => a - b)
  for (let fileNumber of fileNumbers) {
    const length = fileNumber.toString().length
    const x = require(`.${root}${fileNumber.toString()}.js`)
    await x.create()
  }
}

const run = async () => {
  let fileNumbers = await getFiles()
  await createDatabase(fileNumbers)
}

run()
  .then(() => {
    console.log("Database setup successfully!")
    db.end()
    process.exitCode = 0
  })
  .catch(err => {
    console.log("Error creating Database!", err)
  })


x.create代码如下所示:

const dbQ = (query, message) => {
  return new Promise((resolve, reject) => {
    db.query(query, (err, result) => {
      if (err) {
        console.log(`Error: ${err.sqlMessage}`)
        return reject()
      }
      console.log(`Success: ${message}!`)
      return resolve()
    })
  })
}

x.create = async () => {
  const query = `
    CREATE TABLE IF NOT EXISTS Country (
      Code CHAR(2) UNIQUE NOT NULL,
      Flag VARCHAR(1024),
      Name_de VARCHAR(64) NOT NULL,
      Name_en VARCHAR(64) NOT NULL,

      Primary Key (Code)
    )`

  const result = await dbQ(query, "Created Table COUNTRY")
  return result
}

最佳答案

如果您希望每个x.create在下一个开始之前完全执行,即这就是我解释while awaiting each .map call to finish before starting the next的位置-那么可以使用async / await和for循环,如下所示:

const createDatabase = async fileNumbers => {
  fileNumbers.sort((a, b) => a - b);
  for (let fileNumber of fileNumbers) {
    const x = require(`.${root}${fileNumber.toString()}.js`);
    await x.create();
  })
}


但是,这也假设x.create()返回一个Promise-因为您没有显示.${root}${fileNumber.toString()}.js文件的典型内容是什么,所以我只是推测

对问题的另一种解释只是要求您更改createDatabase,以便promises实际上是一个promise数组(目前,它是一个undefined数组

const createDatabase = async fileNumbers => {
  fileNumbers.sort((a, b) => a - b);
  const promises = fileNumbers.map(fileNumber => {
    const x = require(`.${root}${fileNumber.toString()}.js`);
    return x.create();
  })
  await Promise.all(promises);
}


现在,所有.create()都以“并行”运行,但是createDatabase仅解析一次x.create()返回的所有诺言的条件,即-再次假定x.create()返回一个诺言。

关于javascript - 如何等待函数完成后再执行下一个?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59515795/

10-13 06:18