繁体   English   中英

nodejs强大的异步问题

[英]nodejs formidable async issue

我正在使用强大的 3rd 方模块开发 nodejs 应用程序。 我正在尝试让全局 scope 访问(请参阅下面的 var formfields)对下面 form.parse 方法返回的 webform 字段。 首先,form.parse 是一个异步操作,根据此处的模块文档: https://github.com/felixge/node-formidable旨在进行回调。 我正在这样做,请参阅传递给 form.parse 的匿名 function。

我的问题是,无论我做什么,我都无法让 form.parse 正确地将字段 object 返回到全局上下文/范围中的 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 output 中看到的那样,即使我使用回调,执行也会“下降”到最后2个console.log代码行——在运行表单中的console.log行之前.parse 或从 form.parse 正确返回“字段”并将其分配给“var formfields”。

具体来说,console.log output 显示 form.parse 返回 object(字段)成为表单字段。 但它缺少记录为未定义的实际表单数据(例如 formfields.subjects)。 output 的最后一行显示 form.parse 正在获取表单数据(fields.subjects,记录为“生物学”),但没有正确地将其返回为“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 中。 这是可行的,但会产生笨拙的代码。 我希望能找到我的问题的解决方案,因为它会使代码更简洁。 提前感谢您的任何帮助。

您将看到异步JavaScript的基本行为。 看起来您已经意识到了这一点,但以防万一,如果确实令人困惑,我建议您仔细阅读一下。 在Google上进行基本搜索即可找到“ javascript异步性,回调和承诺”。

现在来看语句:

这是可行的,但会使代码笨拙。

从某种意义上讲,我认为这很尴尬,但这是十年前jQuery引入Promises的方式,后来ES2015引入了Promises的方式,后来被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转译。 根据您的编码风格,我想您不一定了解所有这些。 如果为true,则可能需要阅读有关新ECMAScript以及如何使用新功能的信息。

对于任何想知道为什么正确答案在Promise中明确包装formidable.incomingForm().parse()的人,强大的(还)不支持原生承诺。

以下将触发TypeError: is not a function错误,因为它正在寻找回调 function 作为参数:

[fields, files]=await form.parse(req)
    .catch(e => console.log(e));

截至 2022 年 3 月 31 日,强大的团队似乎正在研究parseAsync选项: https://github.com/node-formidable/formidable/issues/685

在此之前,实用程序 function 可以承诺调用:

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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM