无法使用node.js从内部函数访问asynch方法的本地范围

时间:2015-12-03 19:23:13

标签: javascript node.js express closures

我对这个小应用程序有疑问。从我的方法" innerFunc&#34 ;,为" self.words"中的每个单词声明并执行一次。我想访问" outerFunc"的本地范围。

我需要访问" item",对于" innerFunc"的每个声明必须有所不同。

var self = this;
self.words = ["a", "b", "c"];

async.each(self.words,
          function outerFunc (item, callback) {
                var item = item;
                self.item = item;
                var innerFunc = function (error, response, body) {
                    console.log(self.words); //I can access to it.
                    console.log(self.item); //I can access it.
                    console.log(item); //Not accesible -> This is the problem
                    callback(null);
                };

                request("http://blablabla", innerFunc);

            },
          function(err){
            //Do nothing.
          }
        );

问题是我可以访问" self&#34 ;,一个在全局范围内声明的变量。但不是" item"在声明" innerFunc"时在本地范围内声明。我该怎么办?

此外,如果您了解实施此异步任务链的更好模式,欢迎提出建议。

2 个答案:

答案 0 :(得分:0)

最佳做法是使用不同的函数返回您想要的函数,以便每次都能固定不同的“项目”。 试试这段代码:

var self = this;
self.words = ["a", "b", "c"];

var retInnerFunc = function(item) {
        return function(error, response, body) {
                console.log(self.words);
                console.log(self.item);
                console.log(item); 
                callback(null);
            };
};


async.each(self.words,
      function outerFunc (item, callback) {
            var innerItem = item;
            self.item = item;

            request("http://blablabla", retInnerFunc(innerItem));

        },
      function(err){
        //Do nothing.
      }
    );

我还更改了内部var的名称“item”,我不认为这是最好的命名,使用与参数相同的名称...

答案 1 :(得分:0)

好吧,最后我解决了我的问题。事实证明我的解决方案是正确的,尽管可能不是如何构建代码的最好例子。

问题在于我使用Node Inspector v0.12.3来调试我的代码。它提供与WebKit Web Inspector相同的界面。

当我编写应用程序代码时,为了以更快的方式测试我关于闭包的能力,我没有使用item的引用来填充我的方法。我在函数中停止了我的调试器,我试图使用Watch Expression来查看item是否可见。

我的代码是这样的:

...
var item = whatever; //Different value on each iteration.
myFunc = function(error, response, body) {
                console.log(self.words); 
                //stopping debugger and looking for "item" value using Watch Expression
 };
...

Watch Expression的输出为item: <not available>

当我改为正确的方法时:

...
    var item = whatever; //Different value on each iteration.
    myFunc = function(error, response, body) {
                    console.log(self.words);
                    console.log(item);
                    //stopping debugger and looking for item using Watch Expression
     };
...

现在,Watch Expression正在给我正确的值item: whatever

似乎WebKit Web Inspector(或Node Inspector)在您不在方法中使用它们时不提供对这种变量的访问,即使它们应该是可访问的。这同时也是一个愚蠢而棘手的问题。

如果有人使用此调试工具更准确地解释了原因,请分享您的想法:)