Javascript/Node/Express:res.json需要等待函数完成运行后才能返回。。。但是res.json不耐烦吗?

Javascript/Node/Express:res.json需要等待函数完成运行后才能返回。。。但是res.json不耐烦吗?,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,朋友们好!我希望你身体好 在这段代码中,我列出了十台我想查询的服务器。这十台服务器由我在const“ports”中定义的十个端口表示 其思想是在“端口”上使用forEach(),并在每台服务器上运行查询。每次运行查询都会返回一个对象,并将其添加到最初为空的数组“data”中 那么!在“数据”加载了包含我的服务器状态的十个对象之后,我想把它放回客户端 然而。。。。。事实并非如此。forEach()可以很好地运行查询,并将“数据”添加到数组中。。。但在res.json跳枪并将空数据发送回我即将失望的

朋友们好!我希望你身体好

在这段代码中,我列出了十台我想查询的服务器。这十台服务器由我在const“ports”中定义的十个端口表示

其思想是在“端口”上使用forEach(),并在每台服务器上运行查询。每次运行查询都会返回一个对象,并将其添加到最初为空的数组“data”中

那么!在“数据”加载了包含我的服务器状态的十个对象之后,我想把它放回客户端

然而。。。。。事实并非如此。forEach()可以很好地运行查询,并将“数据”添加到数组中。。。但在res.json跳枪并将空数据发送回我即将失望的客户之前

到目前为止。。。我尝试过回调和异步/等待。。。但是我还没有弄明白它的语法。。任何提示都会很棒!谢谢你的时间,朋友们

module.exports = app => {
  app.get("/api/seMapServerStatus", (req, res) => {

  const ports = [ "27111", "27112", "27117", "27118", "27119", "27110", "27115", "27116", "27113", "27114" ]
  const data = []

    function hitServers(port){
        Gamedig.query({
          type: "aGameType",
          host: "theServer'sIP",
          port: port
        }).then((state) => {
          data.push(state)
          console.log("this is the server", state)
        }).catch((error) => {
          console.log("Server is offline");
        });  
    };

    ports.forEach(port => {
      hitServers(port)
    })
  });
  console.log("and here is the final server list", data)
  res.json(data);   
}


上面的代码是同步执行的,因此在任何承诺有机会解决之前,您会在同一帧中返回

我们可以按如下方式清理上述代码:

module.exports=app=>{
app.get(“/api/seMapServerStatus”,(req,res)=>{
常量端口=[“27111”、“27112”、“27117”、“27118”、“27119”、“27110”、“27115”、“27116”、“27113”、“27114”]
功能服务器(端口){
返回Gamedig.query({
类型:“aGameType”,
主机:“服务器的sIP”,
港口:港口
})
}
//具有错误处理功能
函数hitServersSafe(端口){
返回HIT服务器(端口)
。然后(结果=>{
返回{
成功:没错,
结果:结果
}
})
.catch(错误=>{
返回{
成功:错,
//您可能需要序列化错误
错误:错误
}
})
}
const promises=ports.map(port=>hitserver(port))
//具有错误处理功能
//const promises=ports.map(port=>hitServersSafe(port))
允诺
.所有(承诺)
.then(data=>res.json(data))
.catch(错误=>{
//做错事
})
})
}
我们将每个端口映射到一个承诺。在我们有X个承诺的清单之后,我们等待其中的一个完成

调用
Promise.all()
返回一个解析值数组,或在任何Promise被拒绝时拒绝


只有在所有承诺都解决之后,我们才能继续前进,并将结果发送给客户端。

res.json()
不是不耐烦的,您的
forEach()
是不耐烦的。因为对服务器的AJAX调用是异步的,所以在返回数据之前不会填充数据(除非星星对齐)。将导出更改为类似
(app,callback)=>{…
其中callback是一个将数据作为参数的函数。在then块中,可以执行
回调(数据)
回调(res.json(数据))
,任何漂浮在船上的东西。Mm。直接运行此命令将返回“错误捕获”脚本。尝试在任何级别记录数据时,返回的结果都是“挂起”或尚未定义…不必等待!!出现问题的原因是其中一台服务器已关闭。此代码运行良好!谢谢!!太好了!不要忘记返回响应(例如500)如果出现错误,否则客户端将挂起。riiiilight。我现在正在阅读有关使用promise.all处理错误的内容。理想情况下,我希望将好的结果与错误一起传递给客户端,以便切换到客户端。在这种情况下,如果任何一个查询失败,promise.all都将失败。我更新了我的答案,添加了一个安全版本,该版本将捕获t在将承诺传递给
Promise.all()
之前,他会出错并进行转换。