我想对fs.access
和fs.unlink
使用异步等待。这两个函数都返回一个错误,没有结果回调。因此问题在于,如果函数抛出错误,它将直接进入catch块并继续进行下一次迭代。
const unlink = util.promisify(fs.unlink);
const access = util.promisify(fs.access);
const deleteAssetsCtrl = async (req, res) => {
try {
let iteration = 0;
for (let file of fileUrls) {
const fileUrl = file.fileUrl
const fileLocation = path.resolve(contentFolderPath, fileUrl);
access(fileLocation); // step 1
unlink(fileLocation); // step 2
const deleteRowQuery = `DELETE FROM table WHERE fileUrl = '${fileUrl}'`;
executeQuery(deleteRowQuery); // step 3
if (fileUrls.length == iteration){
res.send("true");
} else {
res.send('false')
}
} catch (error) {
console.log('Error =>', error);
res.send(error);
}
}
Error => Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
如何控制流量。 (步骤应按顺序进行)
答案 0 :(得分:3)
您需要在每个异步函数(基本上,所有返回诺言的函数)上添加await
注释
const unlink = util.promisify(fs.unlink);
const access = util.promisify(fs.access);
const deleteAssetsCtrl = async (req, res) => {
try {
let iteration = 0;
for (let file of fileUrls) {
const fileUrl = file.fileUrl
const fileLocation = path.resolve(contentFolderPath, fileUrl);
await access(fileLocation); // step 1
await unlink(fileLocation); // step 2
const deleteRowQuery = `DELETE FROM table WHERE fileUrl = '${fileUrl}'`;
executeQuery(deleteRowQuery); // step 3
if (fileUrls.length == iteration){
res.send("true");
} else {
res.send('false')
}
} catch (error) {
console.log('Error =>', error);
res.send(error);
}
}
这意味着您使用util.promisify
或任何其他方法包装在promise中的所有内容都会创建一个 async 功能,您可以await
进行此操作。
如果您需要从函数本身返回的值,则只有在await
函数的情况下,才可以访问返回值的内容,因为如果没有该关键字,则节点将继续执行并赢得在继续操作之前,不要等待值返回或异步函数完成。
答案 1 :(得分:2)
您必须将await
放在每个承诺的函数之前。
你可以试试吗:
const unlink = util.promisify(fs.unlink);
const access = util.promisify(fs.access);
const deleteAssetsCtrl = async (req, res) => {
try {
let iteration = 0;
for (let file of fileUrls) {
const fileUrl = file.fileUrl
const fileLocation = path.resolve(contentFolderPath, fileUrl);
await access(fileLocation);
await unlink(fileLocation);
const deleteRowQuery = `DELETE FROM table WHERE fileUrl = '${fileUrl}'`;
executeQuery(deleteRowQuery);
if (fileUrls.length == iteration){
res.send("true");
} else {
res.send('false')
}
} catch (error) {
console.log('Error =>', error);
res.send(error);
}
}
编辑:您可能需要在函数await
上使用executeQuery
并可能对其进行赋值……executeQuery
是异步还是同步的?
答案 2 :(得分:1)
承诺只会将功能转换为承诺。您应该使用unlink, access with await
,await将等待,直到该诺言得以解决。
注意:您可能还需要对executeQuery使用await,因为这是异步操作取决于它是否返回promise。
函数内的任何地方迭代都不会增加。
const unlink = util.promisify(fs.unlink);
const access = util.promisify(fs.access);
const deleteAssetsCtrl = async (req, res) => {
try {
let iteration = 0;
for (let file of fileUrls) {
const fileUrl = file.fileUrl
const fileLocation = path.resolve(contentFolderPath, fileUrl);
await access(fileLocation); // step 1
await unlink(fileLocation); // step 2
const deleteRowQuery = `DELETE FROM table WHERE fileUrl = '${fileUrl}'`;
await executeQuery(deleteRowQuery); // step 3
} // is it closed correctly
if (fileUrls.length == iteration){
res.send("true");
} else {
res.send('false')
}
} catch (error) {
console.log('Error =>', error);
res.send(error);
}
}