在闭包内调用父函数

时间:2016-05-10 00:19:06

标签: javascript node.js asynchronous soap callback

我在异步SOAP请求中尝试调用对象函数时非常非常困难。它基本归结为:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.doThing = function() {
        // Get SOAP args
        args = { foo: this.request.cookies.foo };
        // From the SOAP npm package library
        soap.createClient(function(err, client) {
            client.doSomething(args, function(err, result) {
                // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
            });
        });
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

我尝试了很多东西,但我相信它从根本上归结为我不能在任何一个不常用的肥皂功能中调用this.foo()这个事实。虽然我可以将回调函数传递给createClient,如下所示:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.sendSoap = function(err, client) {
        // Get SOAP args
        args = { 
            foo: this.request.cookies.foo <--- this.cookies undefined
        }; 
        client.doSomething(args, function(err, result) {
            // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
        });
    }

    this.doThing = function() {
        // From the SOAP npm package library
        soap.createClient(this.sendSoap);
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

我无法再访问this.request.cookies,因为this现在在sendSoap关闭内部被调用。我不知道为什么javascript将函数作为对象,但我有点沮丧。

我已经尝试了很多很多东西,并且无法找到一种方法来做到这一点并且需要因为对foo的原始调用实际上是一个我在状态itterator模式中使用的递归函数在我用Java编写的SOAP Web服务中进行身份验证。

我能想到的最后一种方法是修改SOAP npm包,以便我可以将this.cookies传递给createClient,而不仅仅是回调。

我真的完全没有想法。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

原因是回调函数中的this通常会引用全局窗口范围。

this是JS开发人员常见的痛苦根源,而且往往没有提及您的想法。您可以在线搜索完整的详细信息。

为什么不这样关闭呢?

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.doThing = function() {
        var self = this; //Closure to the Thing function
        // Get SOAP args
        args = { foo: this.request.cookies.foo };
        // From the SOAP npm package library
        soap.createClient(function(err, client) {
            client.doSomething(args, function(err, result) {
                self.foo();
            });
        });
    }
}

答案 1 :(得分:3)

工作解决方案的多个选项。

一个。将嵌套函数声明为命名函数,或者将匿名函数指定给闭包中的命名变量,允许嵌套函数由闭包中的任何其他函数调用,而不使用this EG

// Either naming a function:
function foo () { console.log("foo") 
// or assigning it to a named variable:
var foo = function() { console.log("foo")};

允许函数在闭包内调用foo()

B中。在this对象构造期间声明设置为Thing值的变量允许闭包内的函数使用变量名访问其实例对象。这与菲利普的答案中包含的技术相同:

`var self = this;`

℃。使用分配给命名变量的匿名arrow functions。可以使用变量名从闭包中的其他嵌套函数调用它们。箭头函数从声明它们的时间和位置绑定this值。因此,箭头函数可以使用Thing访问其this对象实例,而无需单独的self变量别名。 E.G。

var foo = () => {console.log(this.message)};
this.message = "foo was here";
foo();  // logs 'foo was here'

d。当然,设置必须在闭包外部作为对象属性访问的任何参数,嵌套函数或数据值。

// inside constructor
   var foo = () => { /* whatever */ }; // callable within closure as foo()
   this.foo = foo;
// outside constructor
   var thing = new Thing( arg1, arg2);
   thing.foo();                        // callable outside closure as thing.foo()

E)作为构造函数调用时传递给Thing的参数只需使用参数名即可在闭包中访问。要从请求Cookie对象设置名称值对对象,您可能需要object initialiser而不需要this

    args = { 
        foo: request.cookies.foo // request is a parameter
    };