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

我的问题是,无论我做什么,我都无法让 form.parse 正确地将字段对象返回到全局上下文/范围中的 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 行之前.parse 或从 form.parse 正确返回“字段”并将其分配给“var formfields”。

具体来说,console.log 输出显示 form.parse 返回一个对象(字段)以成为表单字段。但它缺少记录为未定义的实际表单数据(例如 formfields.subjects)。输出的最后一行显示 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 的基本行为。看起来您已经意识到这一点,但以防万一,如果它令人困惑,我建议您仔细阅读。一个基本的谷歌搜索“javascript asynchronicity, callbacks and promises”可能就足够了。

现在进入声明:



我想从某种意义上说这很尴尬,但这是大约 10 年前 Promises 由 jQuery 引入,后来被 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 转译。根据您的编码风格,我猜您不一定了解所有这些。如果为真,您可能想了解新的 ECMAScripts 以及如何使用新功能。

关于javascript - nodejs 强大的异步问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53588924/

10-16 02:09