可变范围&回调问题

时间:2016-10-24 10:28:45

标签: json node.js scope callback

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

{
    "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

2 个答案:

答案 0 :(得分:0)

您在上面发布的此功能与异步编程无关。我将在您发布的大量代码的上下文中做出回应。您遇到的错误是因为您正在调用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);

答案 1 :(得分:0)

好。所以你想要一个从嵌套对象中检索名为title的第一个属性和第一个名为extract的属性的函数,无论这些属性有多深层嵌套。

“从对象中提取属性值”本身就是一项任务,我们可以为它编写一个函数。

有三种情况需要处理:

  1. 参数不是对象 - 返回undefined
  2. 参数包含有问题的密钥 - 返回关联值
  3. 否则,递归到对象并重复步骤1和2 - 按结果返回
  4. 看起来像这样:

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