0

所以我有这个异步函数,里面有查询器和 fs.writeFile

(async () => {

...

  if (process.env.IG_USERNAME && process.env.IG_PASSWORD) {
    console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
  } else {
    console.log(`\nInstagram account data is not yet put in \nInputting in...`);

    await inquirer.prompt(questions).then((answers) => {
      let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
      fs.writeFile(".env", file, (err) => {
        if (err) console.log("Something went wrong..");
        else console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
      });
    });
  }

  await login();

...

})();

login();函数需要 .env 变量,我使用查询器输入它,但该login();函数在查询器答案得到处理之前执行。

我应该怎么做才能login();等待直到fs.writeFile完成?

4

2 回答 2

1

简短的回答是只在你的内部使用基于承诺的异步操作,.then()这样你就可以正确地链接所有承诺,然后更高级别await将等待一切​​。在这种情况下,您可以使用return fs.promises.writeFile(...)( 而不是fs.writeFile(...)) 因为fs.promises.writefile(...)返回一个承诺,然后将与父承诺正确链接。

(async () => {

...

  if (process.env.IG_USERNAME && process.env.IG_PASSWORD) {
    console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
  } else {
    console.log(`\nInstagram account data is not yet put in \nInputting in...`);

    await inquirer.prompt(questions).then((answers) => {
      let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
      return fs.promises.writeFile(".env", file);  
    });
  }

  await login();

...

})();

或者,简化一点:

(async () => {

...

  if (process.env.IG_USERNAME && process.env.IG_PASSWORD) {
    console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
  } else {
    console.log(`\nInstagram account data is not yet put in \nInputting in...`);

    const answers = await inquirer.prompt(questions);
    const file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
    await fs.promises.writeFile(".env", file);  
  }

  await login();

...

})();
于 2020-08-16T06:01:47.643 回答
0

通常使用.then()await与承诺一起使用,而不是同时使用。并且login()之前正在执行,因为承诺正在通过.then().

await并且在调用之前没有返回承诺login()

解决方案 1:快速解决方法是await login();在 的回调内部解决fs.writeFile,但随后 login() 的错误也必须处理,这只会使代码开始时更加冗长。

const answers = await inquirer.prompt(questions);
let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
fs.writeFile(".env", file, async (err) => {
  if (err) console.error("Error:fs.writeFile()::", err);
  else console.log(`Used as ${chalk.green(process.env.IG_USERNAME)}`);
  try {
    await login();
  } catch (e) {
    console.error("Error::login():", e);
  }
});

解决方案 2: util.promisify使用 Node >= V8

做出fs.writeFile承诺。

const fs = require("fs");
const { promisify } = require("util");
const promisedWriteFile = promisify(fs.writeFile);

try {
  const answers = await inquirer.prompt(questions);
  let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
  await promisedWriteFile(".env", file);
  await login();
} catch (error) {
  console.error("Any error::", error);
}

解决方案 3: fs Promises API with Node >= V10

try {
  const answers = await inquirer.prompt(questions);
  let file = `IG_USERNAME=${answers.username}\nIG_PASSWORD=${answers.password}\n#ONLINE_MODE=true`;
  await fs.promises.writeFile(".env", file);
  await login();
} catch (error) {
  console.error("Any error::", error);
}
于 2020-08-16T06:02:29.473 回答