从嵌套在函数中的函数返回数组并处理promise promise

时间:2017-04-03 22:54:58

标签: javascript node.js function

我正在使用node.js处理Discord bot。这个想法相当简单,机器人会检查聊天消息中是否有某些短语触发它执行各种操作。主要与提供有关各种游戏服务器的信息有关。

我已经让机器人工作了,它完成了我想要它做的基础知识。

我正在寻求扩展其功能。

基本上当人们键入某个术语(如'server 1v1')时,bot会将连接信息提供给该服务器,并查询服务器的当前状态。

我正在使用npm package called gamedig to do this.

代码如下

//Query Minecraft Server
var serverInfo = function(chatTrigger){

//create an array of servers
//Name of the array arrays within the array is the chat trigger, the first value of each chat trigger array is the query mode for gamedir, second value is the IP or server query URL.
var namedServerArrays = {
    '1v1' : ["csgo","192.168.1.1",2016],
    '10man' : ["csgo","192.168.1.2",27017],
    'minecraft' : ["minecraft","192.168.1.3",2018]
}

//Convert named array data based on the chat triggers to a variable.
//This doesn't have to be done but gamedig gets a little pissy sometimes if you feed it straight arrays. No idea why.
var gameType = namedServerArrays[chatTrigger][0];
var gameHost = namedServerArrays[chatTrigger][1];
var gamePort = namedServerArrays[chatTrigger][2];

//Query server based on chatTrigger input.
Gamedig.query({
        type: gameType,
        host: gameHost,
        port: gamePort
    },
function(e,state) {
        if(e){
            console.log("Server is offline");
            return "Server connection error.";
        }else{
            var playersOnline = state.players.length;
            var currentMap = state.map;

                //Vomit a bunch of error checking.
                console.log("The " + chatTrigger + " server is online.");
                console.log("Players Online: " + playersOnline);
                console.log("Server map: " + currentMap);
                console.log("User was given " + chatTrigger +" server connection information.");

                return [playersOnline,currentMap];
        }
});
//End Query 

var queryReturnState = Gamedig.query();}

我的问题是如何将gamedig查询函数中的数据返回给serverInfo函数,以便serverInfo函数可以将其返回到使用serverInfo函数的任何内容?

在当前状态下,控制台会及时记录所有相关数据,但最终会遇到UnhandledPromiseRejectionWarming。

(node:1479) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot set property 'callback' of undefined (node:1479) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我在理解如何处理node.js中的promise方面遇到了一些麻烦。

对我的任何帮助让我更好地理解并理解。

2 个答案:

答案 0 :(得分:1)

这看起来像底层库中的错误或使用库的问题。尝试使用promise API,它至少会捕获错误,并可能避免在底层gamedig库中使用回调。

使用promise API时,您需要做的就是return一个值或函数值的承诺。

无论您何处致电serverInfo(),都使用.then来处理异步承诺结果,然后将其发送到聊天中,无论是什么。

serverInfo(blah).then(function(result){
   chat.send(result)
})

承诺的代码

// Query Minecraft Server
var serverInfo = function(chatTrigger){
  var namedServerArrays = {
    '1v1' : ["csgo","192.168.1.1",2016],
    '10man' : ["csgo","192.168.1.2",27017],
    'minecraft' : ["minecraft","192.168.1.3",2018]
  }

  // Convert named array data based on the chat triggers to a variable.
  // This doesn't have to be done but gamedig gets a little pissy sometimes if you feed it straight arrays. No idea why.
  var gameType = namedServerArrays[chatTrigger][0];
  var gameHost = namedServerArrays[chatTrigger][1];
  var gamePort = namedServerArrays[chatTrigger][2];

  //Query server based on chatTrigger input.
  return Gamedig.query({
        type: gameType,
        host: gameHost,
        port: gamePort
    })
    .then(function(state){
        var playersOnline = state.players.length;
        var currentMap = state.map;

        //Vomit a bunch of error checking.
        console.log("The " + chatTrigger + " server is online.");
        console.log("Players Online: " + playersOnline);
        console.log("Server map: " + currentMap);
        console.log("User was given " + chatTrigger +" server connection information.");

        return [playersOnline,currentMap];
    })
    .catch(function(error){
        console.error(error);
        return 'Server connection error';
    });
}

答案 1 :(得分:0)

这可能是由代码段底部的var queryReturnState = Gamedig.query();引起的。

根据API,Gamedig.query至少需要一个参数。由于缺少参数,因此很可能尝试在该不存在的对象上设置callback