Javascript 如何在异步继续之前等待(由fs.writeFile)处理查询器应答

Javascript 如何在异步继续之前等待(由fs.writeFile)处理查询器应答,javascript,node.js,fs,inquirer,Javascript,Node.js,Fs,Inquirer,我有一个异步函数,里面有inquirer和fs.writeFile (异步()=>{ ... if(process.env.IG_用户名和process.env.IG_密码){ log(`Used as${chalk.green(process.env.IG_USERNAME)}`); }否则{ console.log(`\n标签帐户数据尚未放入\n放入…`); 等待询问者。提示(问题)。然后((答案)=>{ 让file=`IG_USERNAME=${answers.USERNAME}\nIG_

我有一个异步函数,里面有inquirer和fs.writeFile

(异步()=>{
...
if(process.env.IG_用户名和process.env.IG_密码){
log(`Used as${chalk.green(process.env.IG_USERNAME)}`);
}否则{
console.log(`\n标签帐户数据尚未放入\n放入…`);
等待询问者。提示(问题)。然后((答案)=>{
让file=`IG_USERNAME=${answers.USERNAME}\nIG_PASSWORD=${answers.PASSWORD}\n#ONLINE_MODE=true`;
fs.writeFile(“.env”,文件,(err)=>{
if(err)console.log(“出错了…”);
else console.log(`Used as${chalk.green(process.env.IG_USERNAME)}`);
});
});
}
等待登录();
...
})();
login()
函数需要.env变量,我使用inquirer输入它,但是
login()函数在查询器答案得到处理之前执行


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

简单的回答是在
中只使用基于承诺的异步操作。然后()
这样您就可以正确地链接所有承诺,然后更高级别的
wait
将等待一切。在这种情况下,您可以使用
返回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();

...

})();

通常使用
.then()
等待
并承诺,而不是同时使用。而且,
login()
之前已经被执行,因为承诺是通过
.then()
解决的

并且在调用
login()
之前,不会返回对
等待
的承诺

解决方案1:快速解决方案是解决
等待登录()
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
节点>=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承诺API,节点>=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);
}

我尝试了这两个示例,但下一个语句/函数似乎是先执行的,即使我执行了
console.log(process.env.IG_USERNAME)
它仍然会给我
未定义的
我想我发现了问题。这不是关于承诺,而是关于我在程序顶部需要的.env文件,这样在我下次运行程序时再次需要它之前它不会被更改。我尝试了它,但是
.env
中的数据仍然没有定义,即使在
writeFile()之后
@SyakhiskAl-azmi这应该可以工作了!检查
.env
文件是否具有
let file
字符串的值?这可能是您从
.env
文件读取值的方式。请在问题中更新这一点,以便有更多的上下文。是的,它应该已经起作用了。数据被输入到.env,但我认为我的问题是我加载了
。env
是常量,我仍然找不到重新加载它的方法。谢谢我假设您正在使用 DONTEV环境变量,并且您怀疑它不会重载<代码> .Env
文件并赋值变量(如果<代码> .Env
在某些代码中间更改)。实现此目的的方法:。此外,请考虑接受一个答案,因为他们解决了你的问题中提到的承诺问题。祝你好运