我正在使用强大的第 3 方模块开发一个 Nodejs 应用程序。我正在尝试对下面的 form.parse 方法返回的 webform 字段进行全局范围访问(请参阅下面的 var formfields)。首先,form.parse 是一个异步操作,根据此处的模块文档:https://github.com/felixge/node-formidable 旨在接受回调。我正在这样做,请参阅传递给 form.parse 的匿名函数。
我的问题是,无论我做什么,我都无法让 form.parse 正确地将 fields 对象返回到全局上下文/范围中的 formfields 变量。我已经尝试了(几天)回调函数和返回辅助函数等的闭包的各种组合。但没有运气。
我想做的基本事情是:
var form = new formidable.IncomingForm();
form.encoding = 'utf-8';
var formfields = form.parse(req, function (err, fields, files) {
console.log("within form.parse method, subject field of fields object is: " + fields.subjects);
return fields;
}); // form.parse
console.log("type of formfields is: " + typeof formfields);
console.log("subject field of formfields object is: " + formfields.subjects);
但是正如您从下面的 console.log 输出中看到的那样,即使我使用回调,执行也会“下降”到最后 2 行 console.log 代码 - 在运行 console.log 行之前form.parse 或从 form.parse 正确返回“字段”并将其分配给“var formfields”。
具体来说,console.log 输出显示 form.parse 返回一个对象(字段)以成为表单字段。但它缺少实际的表单数据(例如 formfields.subjects),记录为未定义。输出的最后一行显示 form.parse 正在抓取表单数据(fields.subjects,记录为“biology”),但没有正确地将其返回为“var formfields”。
type of formfields is: object
subject field of formfields object is: undefined
within form.parse method, subject field of fields object is: biology
我没有有解决方案,因为我可以选择仅从 form.parse 中访问和操作字段数据。但我有很多事情需要处理该表单数据(数据库查询、结果格式化、返回客户端),并且它们都必须嵌套在 form.parse 中完成。这是可行的,但会产生尴尬的代码。我希望能找到我的问题的解决方案,因为这将使代码更清晰。预先感谢您的帮助。
现在进入声明:
这是可行的,但会产生尴尬的代码。我想从某种意义上来说这很尴尬,但这是大约 10 年前的方式,当时 jQuery 引入了 Promise,后来由 ES2015 原生引入,后来被
async
方法超越。这可能是您在具体情况下想要的。我假设您的代码包含在某个函数中,如下所示,否则这可能无法正常工作。
async function yourFunction() {
var form = new formidable.IncomingForm();
form.encoding = 'utf-8';
var formfields = await new Promise(function (resolve, reject) {
form.parse(req, function (err, fields, files) {
if (err) {
reject(err);
return;
}
console.log("within form.parse method, subject field of fields object is: " + fields.subjects);
resolve(fields);
}); // form.parse
});
console.log("type of formfields is: " + typeof formfields);
console.log("subject field of formfields object is: " + formfields.subjects);
}
这将强制脚本暂停,直到解析结束。
resolve(fields)
函数调用将确保为您的 formFields 变量分配 fields 对象的值。然后脚本将继续,您的日志将打印您期望的内容。请注意,这不会改变 JS 的工作方式,并且仍然会发生异步调用。
另请注意,这不适用于 NodeJS,因此您必须控制您的环境,因为您需要进行一些 Babel 转译。根据您的编码风格,我猜您不一定了解所有这些。如果属实,您可能想了解新的 ECMAScript 以及如何使用新功能。
formidable.incomingForm().parse()
包装在
Promise
中的人来说,formidable 本身还不支持承诺。以下内容将触发
TypeError: is not a function
错误,因为它正在寻找回调函数作为参数:
[fields, files]=await form.parse(req)
.catch(e => console.log(e));
截至 2022 年 3 月 31 日,强大的团队似乎正在开发一个 parseAsync
选项:https://github.com/node-formidable/formidable/issues/685 在那之前,实用程序函数可以承诺调用:
const ns= {
form_parse: async (req, form) => await new Promise((resolve, reject) => form.parse(req, (e, fields, files) => e ? reject(e) : resolve([fields, files])))
}
允许通过传递表单来实现async/await
流动:
[fields, files]=await ns.form_parse(req, form)
.catch(e => console.log(e));
2024年更新
强大的团队于 2023 年 6 月 17 日parse<FieldKey extends string, FileKey extends string>(
request: IncomingMessage,
): Promise<[Fields<FieldKey>, Files<FileKey>]>;
因此从@3.4.0
我们可以使用经典的await语法:
const form = formidable(options);
const parseResult = await form.parse(request);