【问题标题】:Variable scope & Callback woes变量范围和回调问题
【发布时间】:2016-10-24 10:28:44
【问题描述】:

该程序正在读取嵌套对象以搜索特定的键和值。一旦找到此数据,它必须启动回调以发回数据。对象如下所示:

{
    "name": "joel",
    "title": "CTO",
    "edu": {
        "school": "RMB",
        "college": "GNK",
        "pg": "CDAC",
        "extract": "This is a large text ..."
    }
}

由于我来自同步编程背景,我无法理解何时必须启动回调并确保变量在范围内

function parseData(str, callback) {

   function recursiveFunction(obj) {
       var keysArray = Object.keys(obj);

       for (var i = 0; i < keysArray.length; i++) {
           var key = keysArray[i];
           var value = obj[key];

           if (value === Object(value)) {
               recursiveFunction(value);
           }
           else {
               if (key == 'title') {
                   var title = value;
               }

               if (key == 'extract') {
                   var extract = value.replace(/(\r\n|\n|\r)/gm," ");
                   callback(null, JSON.stringify({title: title, text: extract}));
               }
           }
       }
   }

   recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));
};

执行此代码时,出现以下错误

/parseData.js:29
   recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));
                                                            ^
ReferenceError: title is not defined

【问题讨论】:

  • 如果没有看到您的输入对象和所需的结果,很难回答这个问题。就目前而言,该功能没有多大意义。
  • @Tomalak JSON 数据应该是这样的 { "name": "joel", "title": "CTO", "edu": { "school": "RMB", "college" : "GNK", "pg": "CDAC", "extract": "This is a large text ..." } } 期望的结果是 { "title": "CTO", "extract": "This是大文本..." }
  • 期望的行为/结果是什么?您没有指定该功能应该做什么。此外,正如@Svabael 所述,到目前为止,这与异步编程无关。
  • 程序应该扫描嵌套的 JSON 并选择 2 个键的值,一旦完成,就会将此对象返回给调用模块。另外我不确定这是否是进行回调的正确方法 if (key == 'extract') { var extract = value.replace(/(\r\n|\n|\r)/gm," " );回调(空,JSON.stringify({title:title,text:extract})); } 因为看起来流程突然退出 recursiveFunction。在同步编程中,我们确切地知道这两个值何时可用以及何时发回。
  • 再次:上面的代码中没有异步组件。所有这些都是完全同步的单线程代码。有多少具有title 和extract 属性的对象?一?或者它可以是任何数字? extract 总是 edu 的孩子吗?这可以嵌套多深(换句话说,是否需要递归函数?)

标签: json node.js scope callback


【解决方案1】:

好的。因此,您需要一个从嵌套对象中检索名为 title 的第一个属性和名为 extract 的第一个属性的函数,无论这些属性的嵌套有多深。

“从对象中提取属性值”基本上是一个独立的任务,我们可以为它编写一个函数。

分三种情况处理:

  1. 参数不是对象 - 返回undefined
  2. 参数包含有问题的键 - 返回关联的值
  3. 否则,递归到对象并重复步骤 1 和 2 - 根据结果返回

它可能看起来像这样:

function pluck(obj, searchKey) {
    var val;

    if (!obj || typeof obj !== "object") return;
    if (obj.hasOwnProperty(searchKey)) return obj[searchKey];
    Object.keys(obj).forEach(function (key) {
        if (val) return;
        val = pluck(obj[key], searchKey);
    });
    return val;
}

现在我们可以在任何对象上使用任何键调用pluck(),它会将在对象中任何位置找到的第一个值返回给我们。

现在你剩下的任务变得很容易了:

var obj = {
    "name": "joel",
    "title": "CTO",
    "edu": {
        "school": "RMB",
        "college": "GNK",
        "pg": "CDAC",
        "extract": "This is a large text ..."
    }
}

var data = {
    title: pluck(obj, "title"),
    text: pluck(obj, "extract")
};

【讨论】:

    【解决方案2】:

    您在上面发布的这个函数与异步编程无关。我将在您发布的代码块的上下文中做出回应。您遇到的错误是因为您正在调用 recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract}))); 但未定义 title 变量。我可以看到title 的定义,但它是在recursiveFunction 函数的上下文中。您在其中定义的变量在该函数范围之外是不可见的,这就是您出现此错误的原因。

    你正试图在这一行做一些奇怪的事情: recursiveFunction(str, callback(null, JSON.stringify({title: title, text: extract})));

    此行将调用回调并将此函数的结果传递给 recursiveFunction。我希望在这一行中看到类似的内容: recursiveFunction(str, callback);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      • 2020-07-22
      • 2020-07-24
      • 2011-11-04
      • 2013-12-22
      • 2023-03-25
      相关资源
      最近更新 更多