如何在异步继续之前等待查询者回答被处理(fs.writeFile)
How to wait inquirer answer to be processed (by fs.writeFile) before continuing asynchronously
所以我有这个异步函数 inquirer 和 fs.writeFile inside
(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
完成?
简短的回答是只在你的 .then()
中使用 promise-based 异步操作,这样你就可以正确地链接所有的承诺,然后更高级别的 await
将等待一切。在这种情况下,您可以使用 return fs.promises.writeFile(...)
(而不是 fs.writeFile(...)
),因为 fs.promises.writefile(...)
returns 一个承诺,然后将正确地与父承诺链接。
(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();
...
})();
通常使用带有 promise 的 .then()
或 await
,而不是同时使用。 login()
之前被执行了,因为承诺是通过 .then()
.
解决的
并且在调用 login()
之前没有返回给 await
的承诺。
解决方案 1: 快速修复是在 fs.writeFile
的回调中解决 await login();
,但是 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 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);
}
所以我有这个异步函数 inquirer 和 fs.writeFile inside
(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
完成?
简短的回答是只在你的 .then()
中使用 promise-based 异步操作,这样你就可以正确地链接所有的承诺,然后更高级别的 await
将等待一切。在这种情况下,您可以使用 return fs.promises.writeFile(...)
(而不是 fs.writeFile(...)
),因为 fs.promises.writefile(...)
returns 一个承诺,然后将正确地与父承诺链接。
(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();
...
})();
通常使用带有 promise 的 .then()
或 await
,而不是同时使用。 login()
之前被执行了,因为承诺是通过 .then()
.
并且在调用 login()
之前没有返回给 await
的承诺。
解决方案 1: 快速修复是在 fs.writeFile
的回调中解决 await login();
,但是 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 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);
}