Busboy 在解析所有数据之前完成
Busboy finishes before parsing all data
我有一个 express 应用程序并且有一个函数使用 busboy 解析表单数据,其中 return 是表单的字段值,但在 return 调用之前不解析整个字段.
module.exports = async function (headers, invalidMime, res ,req) {
let fields = {};
const fileWrites = []
let filesToUpload = [];
let finished = false;
const busboy = new Busboy({
headers: headers,
limits: { ileSize: 10 * 1024 * 1024 }
});
await busboy.on("field", (fieldname, val) => {
console.log(fieldname); // Log 1
fields[fieldname] = val;
});
await busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
if (invalidMime(mimetype)) return res.status(404).json({ [fieldname]: "Wrong file type submitted" });
file.on("limit", () => { return res.status(404).json({ general: "File size too large!" }); });
const randomizedFileName = createFileName(filename);
const filePath = path.join(os.tmpdir(), randomizedFileName);
fileWrites.push(createImagePromise(file, filePath, randomizedFileName, mimetype, fieldname));
});
busboy.on("finish", () => {
console.log(fields); // Log 2
});
busboy.end(req.rawBody);
return {filesToUpload: fileWrites, fields: fields}
}
这个 return 我的字段,但缺少最后一个。当我使用控制台日志调试它时,我可以看到 busboy.on("finish")
在我 return 我的值之后执行,这导致缺少变量。
const formData = await FormParser(req.headers, invalidMime, res, req);
console.log(formData); // Log 3
const { fields, filesToUpload } = formData;
var1 // Log 1 - Before return
var2 // Log 1 - Before return
var3 // log 1 - Before return
{ filesToUpload: [], // Log 3 - After return
fields:
{ var1: 'var1',
var2: 'var2',
var3: 'var3' } }
var4 // Log 1 - After return
{ var1: 'var1', // Log 2 - After return
var2: 'var2',
var3: 'var3',
var4: 'var4' }
如何在 busboy 完成解析后将其设为 return 值?
当您在各处添加一些 await
时,异步函数不会神奇地变成同步函数。
例如,这没有意义:
await busboy.on("field", (fieldname, val) => {
console.log(fieldname); // Log 1
fields[fieldname] = val;
});
你认为它以某种方式等待 fields
对象被填充,但它 实际上 做的是:它等待 .on()
函数return,并且此函数 returns 立即 。它唯一的工作是分配一个事件处理程序。 field
事件甚至还没有发生。
异步编程的解决方案始终是:在事件处理程序中执行表示任务已完成的工作。您正在尝试在函数的最后一行完成工作 (return {filesToUpload: fileWrites, fields: fields}
),就好像最后一行是 运行 的最后一件事一样。不是这样的。
一旦将需要对事件做出反应的位移到事件处理程序中,您会发现整个函数不需要async
在全部.
免责声明:以下代码未经测试,我之前没有使用过busboy,按的意思去做,不一定按它说的去做。
module.exports = function (headers, invalidMime, res, req) {
let fields = {};
let pendingFileWrites = [];
const busboy = new Busboy({
headers: headers,
limits: { fileSize: 10 * 1024 * 1024 }
});
busboy.on("filesLimit", () => {
res.status(400).json({ error: "File size too large!" });
});
busboy.on("error", () => {
res.status(500).json({ error: "Error parsing data" });
});
busboy.on("field", (fieldname, val) => {
fields[fieldname] = val;
});
busboy.on("finish", () => {
Promise.all(pendingFileWrites).then((fileWrites) => {
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
});
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
console.log(`Processing [{filename}] ({mimetype})`);
if (invalidMime(mimetype)) return res.status(404).json({ [fieldname]: "Wrong file type submitted" });
file.on("limit", () => { return res.status(404).json({ general: "File size too large!" }); });
file.on("end", () => { console.log(`Done processing [{filename}] ({mimetype})`); });
const randomizedFileName = createFileName(filename);
const filePath = path.join(os.tmpdir(), randomizedFileName);
pendingFileWrites.push(createImagePromise(file, filePath, randomizedFileName, mimetype, fieldname));
});
};
请注意,您可以这样 async
:
busboy.on("finish", () => {
Promise.all(pendingFileWrites).then((fileWrites) => {
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
});
喜欢
busboy.on("finish", async () => {
var fileWrites = await Promise.all(pendingFileWrites);
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
甚至
busboy.on("finish", async () => {
res.json({
filesToUpload: await Promise.all(pendingFileWrites),
fields: fields
});
});
如果你愿意的话。在任何一种情况下,您都需要添加错误处理(前者通过 .catch()
,后者通过 try
/catch
块)。
我有一个 express 应用程序并且有一个函数使用 busboy 解析表单数据,其中 return 是表单的字段值,但在 return 调用之前不解析整个字段.
module.exports = async function (headers, invalidMime, res ,req) {
let fields = {};
const fileWrites = []
let filesToUpload = [];
let finished = false;
const busboy = new Busboy({
headers: headers,
limits: { ileSize: 10 * 1024 * 1024 }
});
await busboy.on("field", (fieldname, val) => {
console.log(fieldname); // Log 1
fields[fieldname] = val;
});
await busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
if (invalidMime(mimetype)) return res.status(404).json({ [fieldname]: "Wrong file type submitted" });
file.on("limit", () => { return res.status(404).json({ general: "File size too large!" }); });
const randomizedFileName = createFileName(filename);
const filePath = path.join(os.tmpdir(), randomizedFileName);
fileWrites.push(createImagePromise(file, filePath, randomizedFileName, mimetype, fieldname));
});
busboy.on("finish", () => {
console.log(fields); // Log 2
});
busboy.end(req.rawBody);
return {filesToUpload: fileWrites, fields: fields}
}
这个 return 我的字段,但缺少最后一个。当我使用控制台日志调试它时,我可以看到 busboy.on("finish")
在我 return 我的值之后执行,这导致缺少变量。
const formData = await FormParser(req.headers, invalidMime, res, req);
console.log(formData); // Log 3
const { fields, filesToUpload } = formData;
var1 // Log 1 - Before return
var2 // Log 1 - Before return
var3 // log 1 - Before return
{ filesToUpload: [], // Log 3 - After return
fields:
{ var1: 'var1',
var2: 'var2',
var3: 'var3' } }
var4 // Log 1 - After return
{ var1: 'var1', // Log 2 - After return
var2: 'var2',
var3: 'var3',
var4: 'var4' }
如何在 busboy 完成解析后将其设为 return 值?
当您在各处添加一些 await
时,异步函数不会神奇地变成同步函数。
例如,这没有意义:
await busboy.on("field", (fieldname, val) => {
console.log(fieldname); // Log 1
fields[fieldname] = val;
});
你认为它以某种方式等待 fields
对象被填充,但它 实际上 做的是:它等待 .on()
函数return,并且此函数 returns 立即 。它唯一的工作是分配一个事件处理程序。 field
事件甚至还没有发生。
异步编程的解决方案始终是:在事件处理程序中执行表示任务已完成的工作。您正在尝试在函数的最后一行完成工作 (return {filesToUpload: fileWrites, fields: fields}
),就好像最后一行是 运行 的最后一件事一样。不是这样的。
一旦将需要对事件做出反应的位移到事件处理程序中,您会发现整个函数不需要async
在全部.
免责声明:以下代码未经测试,我之前没有使用过busboy,按的意思去做,不一定按它说的去做。
module.exports = function (headers, invalidMime, res, req) {
let fields = {};
let pendingFileWrites = [];
const busboy = new Busboy({
headers: headers,
limits: { fileSize: 10 * 1024 * 1024 }
});
busboy.on("filesLimit", () => {
res.status(400).json({ error: "File size too large!" });
});
busboy.on("error", () => {
res.status(500).json({ error: "Error parsing data" });
});
busboy.on("field", (fieldname, val) => {
fields[fieldname] = val;
});
busboy.on("finish", () => {
Promise.all(pendingFileWrites).then((fileWrites) => {
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
});
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
console.log(`Processing [{filename}] ({mimetype})`);
if (invalidMime(mimetype)) return res.status(404).json({ [fieldname]: "Wrong file type submitted" });
file.on("limit", () => { return res.status(404).json({ general: "File size too large!" }); });
file.on("end", () => { console.log(`Done processing [{filename}] ({mimetype})`); });
const randomizedFileName = createFileName(filename);
const filePath = path.join(os.tmpdir(), randomizedFileName);
pendingFileWrites.push(createImagePromise(file, filePath, randomizedFileName, mimetype, fieldname));
});
};
请注意,您可以这样 async
:
busboy.on("finish", () => {
Promise.all(pendingFileWrites).then((fileWrites) => {
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
});
喜欢
busboy.on("finish", async () => {
var fileWrites = await Promise.all(pendingFileWrites);
// NOW we're done
res.json({
filesToUpload: fileWrites,
fields: fields
});
});
甚至
busboy.on("finish", async () => {
res.json({
filesToUpload: await Promise.all(pendingFileWrites),
fields: fields
});
});
如果你愿意的话。在任何一种情况下,您都需要添加错误处理(前者通过 .catch()
,后者通过 try
/catch
块)。