我试图上传一个图片使用一个组件(summernote)的角度形式。
我将uploadImagePath端点配置为将映像提交到nodejs后端,但在我的代码中,outputFileName字段是空的。
如何确保函数完成?
async uploadFile(req) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
let outputFileName = '';
try {
form.parse(req, function(err, fields, files) {
var imgArray = files.image;
for (var i = 0; i < imgArray.length; i++) {
var singleImg = imgArray[i];
outputFileName = singleImg.originalFilename;
fs.readFile(singleImg.path , function(err,data) {
fs.writeFile('./public/images/'+outputFileName,data, function(err) {
if (err) console.log('ERRRRRR!! :'+err);
console.log('Fitxer: ' + outputFileName);
})
})
}
});
}
catch (ex) {
throw ex;
}
return { error: false, outputFileName: outputFileName, msg: "File uploaded!" };
}发布于 2021-02-19 10:01:23
您不应该直接调用接受async函数中回调的函数。这就是为什么尝试捕捉错误的机会较小的原因。相反,返回一个Promise来处理该错误。
function uploadFile(req) {
return new Promise((resolve, reject) => {
const multiparty = require('multiparty')
const form = new multiparty.Form()
let outputFileName = ''
form.parse(req, function (err, fields, files) {
if (err) {
reject(err)
return
}
const imgArray = files.image
// You should not call function that accepts a callback in for loop
// Lets assumed imageArray has only one element.
// for (let i = 0; i < imgArray.length; i++) {
const singleImg = imgArray[0 /* i */]
outputFileName = singleImg.originalFilename
fs.readFile(singleImg.path, function (err, data) {
if (err) {
reject(err)
return
}
fs.writeFile('./public/images/' + outputFileName, data, function (err) {
if (err) {
reject(err)
return
}
console.log('Fitxer: ' + outputFileName)
resolve({
error: false,
outputFileName: outputFileName,
msg: "File uploaded!"
})
})
})
// }
});
})
}但是正如您所看到的,上面的代码是混乱的,并且for-循环不起作用。要解决这个问题,我们应该使uploadFile异步,其中不能使用回调。
如果可能,async函数应该调用返回Promise的另一个函数,这样await关键字可以帮助简化代码并处理抛出的错误。为此,编写一个新函数来实现form.parse异步,并替换支持返回Promise的东西的fs,例如fs.Promise API或fs-extra package。
const fs = require('fs-extra')
const multiparty = require('multiparty')
function parseForm(req) {
return new Promise((resolve, reject) => {
const form = new multiparty.Form()
form.parse(req, function (err, fields, files) {
if (err) reject(err)
else resolve(files)
})
})
}
async function uploadFile(req) {
let outputFileName = ''
const files = await parseForm(req)
const imgArray = files.image
// Now we can use for loop
for (let i = 0; i < imgArray.length; i++) {
const singleImg = imgArray[i]
outputFileName = singleImg.originalFilename
const data = await fs.readFile(singleImg.path)
await fs.writeFile('./public/images/' + outputFileName, data)
console.log('Fitxer: ' + outputFileName)
}
return {
error: false,
outputFileName: outputFileName,
msg: "File uploaded!"
}
}不过,您的代码中仍然存在一些问题。outputFileName被分配了不止一次,这使得您的目标很难理解。由于这个原因,我不能重写您所期望的代码。
顺便说一句,应该考虑到更多的条件。我不想多谈这件事。
var keyword声明局部变量。在for-循环中使用const或let关键字使用await关键字,除非要逐个迭代元素。发布于 2021-02-19 10:01:34
最简单的方法是制作一个助手函数,使nodestyle fn返回一个承诺,然后使用它。
function parseMultiparty(req) {
return new Promise((resolve, reject) => {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
if(err) reject(err) else resolve([fields, files])
})
})
}async uploadFile(req) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
let outputFileName = '';
try {
const [fields, files] = await parseMultiparty(req)
var imgArray = files.image;
for (var i = 0; i < imgArray.length; i++) {
var singleImg = imgArray[i];
outputFileName = singleImg.originalFilename;
const data = await fs.promises.readFile(singleImg.path)
console.log('Fitxer: ' + outputFileName);
try {
await fs.promises.writeFile('./public/images/'+outputFileName,data)
} catch(err) { console.log('ERRRRRR!! :'+err);}
}
}
catch (ex) {
throw ex;
}
return { error: false, outputFileName: outputFileName, msg: "File uploaded!" };
}https://stackoverflow.com/questions/66275184
复制相似问题