【问题标题】:Fill an array based on a get response express根据 get response express 填充数组
【发布时间】:2018-08-11 17:52:44
【问题描述】:

我有以下 server.js 获取路由

app.get('/', function(req, res) {
var url;
var final_res = [];
endpoints.forEach(function(url){
    request(url, function(error,response,body){
        if(!error && response.statusCode == 200){
            final_res.push(url.url);
            console.log(url.url);
        }else{
            res.send(err);
            console.log(err);
        }
    });
});
});

这是我的客户端 js,我在其中使用 jQuery 获取完全相同的获取

$(document).ready(function() {
$.get('http://localhost:3000/', function(data) {
    console.log(data);
    $("#body").text(data);
});
});

当我打开 index.html 时,它会正确显示用户界面,并在我执行 server.js 的终端内正确显示 url。我无法完成的是如何使用我的 jQuery 接收到的数据来填充我的 html 中的表格。我的表将填充从我的端点获取的 url。

我有一些 nodejs 的背景知识,但我无法总结。

【问题讨论】:

    标签: javascript jquery node.js ajax


    【解决方案1】:

    您必须等待所有请求得到解决,然后将final_res 数组发送回客户端。您可以使用async/awaitPromise.all 概念来做到这一点。如果您不想使用这些资源,则需要手动计数并等待所有请求,使用计数器了解所有请求何时完成,如下所示:

    app.get('/', function(req, res) {
        var url;
        var final_res = [];
        var respCounter = endpoints.length;
        endpoints.forEach(function(url){
            request(url, function(error,response,body){
                respCounter--;
                if(!error && response.statusCode == 200){
                    final_res.push(url.url);
                    console.log(url.url);
                }else{
                    res.send(err);
                    console.log(err);
                }
                if(respCounter == 0) {
                    res.send(final_res);
                }
            });
        });
    });
    

    【讨论】:

      【解决方案2】:

      由于您需要知道多个请求何时完成,我建议您切换到使用 request-promise 库,以便您可以使用 Promise 跟踪所有请求何时完成。该库还会自动为您检查 statusCode。所以,你可以这样做:

      const rp = require('request-promise');
      
      app.get('/', function(req, res) {
          Promise.all(endpoints.map(url => {
              return rp(url).then(r => {
                  return url.url;
              }).catch(err => {
                  // rather than error, just return null result
                  return null;
              })
          })).then(results => {
              // filter out null values, then send array as the response
              res.json(results.filter(item => item !== null));
          }).catch(err => {
              console.log(err);
              res.sendStatus(500);
          });
      });
      

      这将并行运行所有请求,但按顺序收集结果,这将导致最快的整体运行时间。

      如果你想一次运行它们,你可以像这样使用 async/await:

      const rp = require('request-promise');
      
      app.get('/', async function(req, res) {
          let results = [];
          for (let url of endpoints) {
              try {
                  let r = await rp(url);
                  if (r) {
                      results.push(url.url);
                  }
              } catch(e) {
                  // ignore error
              }
          }
          res.json(results);
      });
      

      2020 年 1 月编辑 - request() 模块处于维护模式

      仅供参考,request 模块及其衍生模块如request-promise 现在处于维护模式,不会积极开发以添加新功能。你可以阅读更多关于推理的信息herethis table 中有一个备选方案列表,其中对每个备选方案进行了一些讨论。我自己一直在使用got(),它从一开始就是使用 Promise 构建的,而且使用简单。

      【讨论】:

      • 太棒了,它看起来更干净,使用 promises 我现在唯一遇到的问题是我收到了一个 CORS 错误:跨域请求被阻止:同源策略不允许读取localhost:3000 的远程资源. (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。我不明白为什么如果我的节点正在发出请求并且我只调用我的端点来获取此信息@jfriend00
      • @user2737948 - 您是否在浏览器中收到 CORs 错误?如果是这样,浏览器会在您发出 ajax 请求的页面的 URL 栏中显示什么?
      • 我在另一个窗口中打开我的索引,并指出我文档中的地址。是否有必要将我的索引放在我的 nodejs 服务器中?
      • @user2737948 - 你没有回答我在之前的评论中提出的任何一个问题,我不知道你最后的评论是什么意思。如果要对http://localhost:3000 进行Ajax 调用,则还需要从同一服务器加载网页,以便浏览器中的URL 以http://localhost:3000 开头。如果你是直接从文件系统加载网页,你不能对http://localhost:3000做ajax。
      猜你喜欢
      • 2022-08-14
      • 2018-09-10
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2011-03-10
      • 2015-02-19
      相关资源
      最近更新 更多