最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

在模块中两次调用相同的函数失败

运维笔记admin14浏览0评论

在模块中两次调用相同的函数失败

在模块中两次调用相同的函数失败

我正在创建一个node.js模块来与机器人交互,我必须根据另一个REST调用的结果获得一个REST资源(两者都是GET)。

当我这样做时,我首先调用模块中的一个函数来构造REST资源的url,然后我在“node-rest-client”模块中使用它。

问题是我需要将这个模块用于多个机器人,这些机器人具有单独的ip地址和一些不同于机器人到机器人的其他参数(如果你愿意,我需要将它作为一个类使用)。

我的模块被称为mir100.js,如下所示

var Client = require('node-rest-client').Client;
var rest = new Client(); 

/* Make the mir function act as a constructor
* use: var robot = new mir("192.168.42.111");
* or: var robot = new mir();//default ip = 192.168.12.20
*/
module.exports = mir;
function mir(ip) {
    this.g_robotPositions = [];
    this.HOST = "192.168.12.20";
    this.PORT = "8080";
    this.VERSION = "v1.0.0";
    if(arguments.length === 1){ 
        console.log("IP address is defined as argument: " + ip);
        this.HOST = ip; 
    }
}

/** Construct url
* Private function/method
* @param {string} path is the path of the url resource
* @param {boolean} predefined if true, this is indicates the path is taken from the MiR REST (includes /v1.0.0/...) default=false
* @return {string} url to the desired resource
*/
mir.prototype.ConstructURL = function(path, predefined){
    if(predefined == "undefined") predefined = false;
    if(predefined == true){
        return "http://" + this.HOST + ":" + this.PORT + path;
    }
    var url = "http://" + this.HOST + ":" + this.PORT + "/" + this.VERSION
    if(path[0] == '/') url += path;
    else url += "/" + path;
    return url;
}

/** Get all details about positions belonging to a specific map (guid) 
* @param map The map guid to get positions from
* @param callback A callback function, that returns any errors that might have occurred. The callback function takes the standard javascript argument format of (error, data)
*/
mir.prototype.GetPositionsFromMap = function(map,callback){
    g_robotPositions = [];
    var url = this.ConstructURL("maps/" + map + "/positions");

    var req = rest.get(url,function(data,response){
        if(response.statusCode >= 200 && response.statusCode < 300){

            var posCnt = data.length;
            for(var ii in data){
                console.log("data["+ii+"].url: " + data[ii].url);
                // This call to ConstructURL(...) fails and says "TypeError: this.ConstructURL is not a function"
                var tmpUrl = this.ConstructURL(data[ii].url);

                var req2 = rest.get(tmpUrl,function(data,response2){
                    if(response2.statusCode >= 200 && response2.statusCode < 300){
                        g_robotPositions.push(data);
                        if(g_robotPositions.length == posCnt){
                            callback(null,g_robotPositions);
                        }
                    }
                    else{
                        var error2 = {
                            "error":response2.statusCode,
                            "url":tmpUrl,
                            "robot":this.HOST,
                            "source":"mir100.js - GetPositionsFromMap()"
                        }
                        console.log(JSON.stringify(error2),error2.source,{"robot":this.HOST});
                        callback(error, null);
                    }
                });

                req2.on("error",function(err2){
                    console.log("Error GetPositionsFromMap 2: " + err2);
                });
            }
        }
        else{
            error = {
                "error":response.statusCode,
                "url":url,
                "robot":this.HOST,
                "source":"mir100.js - GetPositionsFromMap()"
            }
            console.log(JSON.stringify(error),error.source,{"robot":this.HOST});
            callback(error, null);
        }
    });

    req.on("error",function(err){
        console.log(err,"mir100.js - GetPositionsFromMap()",{"robot":this.HOST})
        callback(err, null);
    });
}

/** Get a list of all the maps on the robot 
* @param callback A callback function, that returns any errors that might have occurred. The callback function takes the standard javascript argument format of (error, data)
*/
mir.prototype.GetMaps = function(callback){
    var url = this.ConstructURL("maps");

    var req = rest.get(url,function(data,response){
        if(response.statusCode >= 200 && response.statusCode < 300){
            callback(null, data);
        }
        else{
            error = {
                "statusCode":response.statusCode,
                "url":url,
                "robot":this.HOST,
                "source":"mir100.js - GetMaps()"
            }
            console.log(JSON.stringify(error),error.source,{"robot":this.HOST});
            callback(JSON.stringify(error), null);
        }
    });

    req.on("error",function(err){
        console.log(err,"mir100.js - GetMaps()",{"robot":this.HOST})
        callback(err, null);
    });
}

在我的主node.js中我有以下内容:

var mir = require('./mir100.js');

var robot = new mir();

robot.GetMaps( function(err,data){
    if(!err){
        robot.GetPositionsFromMap(data[1].guid,function(err,posData){
            if(!err){
                console.log("getPositionsFromMap: " + JSON.stringify(data));
            }
            else{
                console.log("Error getPositionsFromMap: " + err); 
            }
        });

    }
    else{
        console.log("Error GetMaps: " + err); 
    }
});

当我运行代码时,我在控制台中收到以下错误

TypeError: this.ConstructURL is not a function
    at C:\Projects\Active\AL10-2.0\al10-server\js\mir100.js:498:23
    at C:\Projects\Active\AL10-2.0\al10-server\node_modules\node-rest-client\lib\node-rest-client.js:539:13
    at Object.parse (C:\Projects\Active\AL10-2.0\al10-server\node_modules\node-rest-client\lib\nrc-parser-manager.js:142:13)
    at ConnectManager.handleResponse (C:\Projects\Active\AL10-2.0\al10-server\node_modules\node-rest-client\lib\node-rest-client.js:538:32)
    at ConnectManager.handleEnd (C:\Projects\Active\AL10-2.0\al10-server\node_modules\node-rest-client\lib\node-rest-client.js:531:18)
    at IncomingMessage.<anonymous    (C:\Projects\Active\AL10-2.0\al10-server\node_modules\node-rest-client\lib\node-rest-client.js:678:34)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)

为什么我无法使用此功能两次?我担心它与围绕调用ConstructURL()的for循环有关,但我不明白为什么那会是一个问题......

回答如下:

问题是关于this在函数内部调用时的上下文。

在为bind(this)声明回调函数时,你应该使用rest.get

var req = rest.get(url,(function(data,response){...}).bind(this));

而且,req.on("error", ...)也是如此。

以下是GetPositionsFromMap的完整代码:

/** Get all details about positions belonging to a specific map (guid) 
* @param map The map guid to get positions from
* @param callback A callback function, that returns any errors that might have occurred. The callback function takes the standard javascript argument format of (error, data)
*/
mir.prototype.GetPositionsFromMap = function(map,callback){
    g_robotPositions = [];
    var url = this.ConstructURL("maps/" + map + "/positions");

    var req = rest.get(url,(function(data,response){
        if(response.statusCode >= 200 && response.statusCode < 300){

            var posCnt = data.length;
            for(var ii in data){
                console.log("data["+ii+"].url: " + data[ii].url);
                // This call to ConstructURL(...) fails and says "TypeError: this.ConstructURL is not a function"
                var tmpUrl = this.ConstructURL(data[ii].url);

                var req2 = rest.get(tmpUrl,function(data,response2){
                    if(response2.statusCode >= 200 && response2.statusCode < 300){
                        g_robotPositions.push(data);
                        if(g_robotPositions.length == posCnt){
                            callback(null,g_robotPositions);
                        }
                    }
                    else{
                        var error2 = {
                            "error":response2.statusCode,
                            "url":tmpUrl,
                            "robot":this.HOST,
                            "source":"mir100.js - GetPositionsFromMap()"
                        }
                        console.log(JSON.stringify(error2),error2.source,{"robot":this.HOST});
                        callback(error, null);
                    }
                });

                req2.on("error",function(err2){
                    console.log("Error GetPositionsFromMap 2: " + err2);
                });
            }
        }
        else{
            error = {
                "error":response.statusCode,
                "url":url,
                "robot":this.HOST,
                "source":"mir100.js - GetPositionsFromMap()"
            }
            console.log(JSON.stringify(error),error.source,{"robot":this.HOST});
            callback(error, null);
        }
    }).bind(this));

    req.on("error",(function(err){
        console.log(err,"mir100.js - GetPositionsFromMap()",{"robot":this.HOST})
        callback(err, null);
    }).bind(this));
}
发布评论

评论列表(0)

  1. 暂无评论