简体   繁体   English

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

[英]How to execute these functions after one another / after one is fully done?

I've got the following function, which doesn't execute in the order I'd like it to.我有以下函数,它没有按照我想要的顺序执行。

The console.log within the callback actually gets fired before the loop within the function itself even executes.回调中的 console.log 实际上在函数本身的循环执行之前就被触发了。 So to sum it up I'd like the function "getFiles" to fully finish before the next one "createDatabase" starts to execute.总而言之,我希望函数“getFiles”在下一个“createDatabase”开始执行之前完全完成。

Thanks for your help.谢谢你的帮助。 I'm already going nuts about this issue :(我已经对这个问题发疯了:(

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()

This would be fairly straightforward to code with the newer fs.promises interface so you can await the readdir() output:使用较新的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);
});

Summary of Changes:变更概要:

  1. Use fs.promises interface so we can await the results of readdir() .使用 fs.promises 接口,以便我们可以await readdir()的结果。
  2. Change getFiles() to be async so we can use await and so it returns a promise that is resolved when all the asynchronous work is done.getFiles()更改为async以便我们可以使用await ,因此它返回一个在所有异步工作完成后解析的 promise。
  3. Move data into the functions (resolved from getFiles() and passed to createDatabase() ) rather than being a top level variable that is shared by multiple functions.data移动到函数中(从getFiles()解析并传递给createDatabase() ),而不是成为多个函数共享的顶级变量。
  4. Track completion and errors from calling run()跟踪调用run()完成情况和错误
  5. Actually call getFiles() with parens after it in run() .实际上在run()之后用括号调用getFiles() run()

Following code snippet will first completely run getFiles function and then run the createDatabase function.以下代码片段将首先完全运行 getFiles 函数,然后运行 ​​createDatabase 函数。 For using async/await, a function needs to return a promise(Read about promises here ).对于使用 async/await,函数需要返回一个 promise( 在此处阅读 promises)。

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()

Since the createDatabase function is not returning any promise right now, you can remove await in front of it.由于 createDatabase 函数现在没有返回任何承诺,您可以删除它前面的 await。 Await is used only if a promise is returned. Await 仅在返回承诺时使用。 You can read about async/await here .您可以在此处阅读有关 async/await 的信息

The problem is related to using a forEach loop for asynchronous code.该问题与对异步代码使用 forEach 循环有关。 This answer has more on the issue:这个答案有更多关于这个问题:

Using async/await with a forEach loop 在 forEach 循环中使用 async/await

I am not really sure what exactly you are trying to do but looks like the problem is in your run function.我不太确定你到底想做什么,但看起来问题出在你的运行函数中。 You are not calling getFiles function inside run.您没有在 run 中调用 getFiles 函数。 You care just mentioning the function name.您只关心提及函数名称。 Also needs to wrap the getFiles in promise it should be还需要将getFiles包装在承诺中,它应该是

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM