【问题标题】:How do I assign my get response data to an array in the order I sent the request如何按照发送请求的顺序将获取响应数据分配给数组
【发布时间】:2017-07-24 18:58:06
【问题描述】:

我在 for 循环中有一个 rest.get 请求,它发送大约 20 个查询(基于每次更改查询的先前请求的数据)。我的问题是它似乎完全运行了 for 循环,然后查询异步运行,并以最快而不是连续返回的数据响应。如果我 console.log 在 .end 函数内记录 forloop 的索引,则在 forloop 完成之前它是未定义的,然后它是最终数字(即使它都在 for 循环内)。我正在尝试以与发送请求相同的顺序保存(推送到数组)数据,因此我可以将数据与之前打印的获取响应列表相匹配。有没有办法按照我发送请求的顺序将我的响应数据分配给一个数组,而不是先到先得?

// this function is being called inside the previous query 
function carData(req, res) {

  var carNameJson = [];
  var resultToJson = [];

  //singleCars.length is defined in a previous query and is an array of car IDs
  for (var index = 0; index < singleCars.length; ++index) {
    //Grab each individual car ID and concatinate it into a Query
    var carNames = singleCars[index];
    var carQuery = "https://queryinfo";
    var finalSingleQuery = "carQuery + carNames";

    // puts the data into an array of JSON objects
    carNameJson = {
      carID: carNames
    };

    // result is a global variable assigned as an empty array
    // it list all the car IDs in a JSON format
    result.push(carNameJson);

    rest
      .get(finalSingleQuery)
      .proxy("http://proxyinfo")
      .end(function(resp) {
        resultToJson = {
          carInfo: resp.body
        };
     // resultInfo is a global variable assigned as an empty array
        resultInfo.push(resultToJson);
        return resultToJson;
      });
  }
}

这段代码一切正常,但它给我的数据是乱序的,所以我无法将汽车信息与汽车 ID 列表匹配。我是节点新手,所以我可能做错了。任何帮助将不胜感激!

【问题讨论】:

  • 如何为每个请求发送一个当前时间戳,该时间戳会传播到响应中,然后按时间戳对响应进行排序。
  • 您的另一种选择是重构它,以便您发出一个包含 20 个值的请求,其响应在一个响应中的一个数组中全部获取,并且按照您希望它们的精确顺序是。然后你有 1) 更少的请求来回和转发,以及 2) 异步代码的问题更少。
  • 没关系时间戳...在我看来,您根本没有使用 req 变量。该变量是您的请求,它可能包含重要数据,例如 ID,然后您可以在 JSON 响应中与其他数据一起返回这些数据。我很奇怪您没有使用 req 变量,并且每次请求都返回相同的内容。
  • 它仍然会使请求异步,但它只是一个获取所有数据的请求。并且应该比 20 个请求快(因为每个 HTTP 请求都有建立连接的开销成本)。但是,如果您说您无法控制后端,那么除非您可以调用另一种方法来批量获取汽车数据(而不是像现在看起来那样一次一辆车),否则您可能会有点卡住了。
  • var finalSingleQuery = "carQuery + carNames" 还能用吗?那不应该没有双引号吗?

标签: javascript arrays rest request response


【解决方案1】:

您可以使用索引变量来定位存储响应的位置。为此,您必须确保index 变量是for 主体的本地变量,您可以使用let(而不是var)来实现:

for (let index = 0; index < singleCars.length; ++index) {

    // ...

    // store directly at the correct index:
    resultInfo[index] = resultToJson;

您可能还想知道何时获得所有结果。在分配给resultInfo[index] 之后,您可以使用此条件执行此操作:

    if (resultInfo.filter(Object).length === singleCars.length) {
        // maybe call a callback here.
    }

【讨论】:

  • 我试过 ` if (resultInfo.filter(Number).length === singleCars.length) { // 也许在这里调用回调。 }` 但 resultInfo.filter(Number).length 总是返回 0。
  • 好你找到了方法!我更新为Object 而不是Number,但Object.keys 也可以正常工作。
【解决方案2】:

您正在 for 循环内执行安静的响应。相反,请考虑构建一个完整的 JSON 对象,其中包含客户端所需的所有数据(换句话说,将其全部作为 1 个大响应发送,而不是大量小响应)。

使用 for 循环构建 JSON,然后在循环之外执行您的 1-time restful 响应。

这样你就不必担心数据乱序通过,响应完整,不会丢失索引等重要信息。

【讨论】:

  • 这会使其同步吗?我需要它同时运行所有 20 个请求。
  • 为什么需要 20 个请求而不是 1 个请求。不,它仍然是异步的。该页面无需重新加载即可获取新数据。
  • 每次请求时carID都会改变,所以不是每次都需要不同的请求吗?
  • stackoverflow.com/a/19911657/6416639(用你提到的JSON切换url变量)你指的是这个吗?
  • 问题是,您一次发送了 20 个响应。与其一次发送 20 个响应,不如发送 1 个响应 1 次,并让它包含 20 个不同的东西。
猜你喜欢
  • 1970-01-01
  • 2021-10-25
  • 2017-07-14
  • 1970-01-01
  • 2019-10-09
  • 1970-01-01
  • 2011-12-21
  • 2018-05-01
  • 1970-01-01
相关资源
最近更新 更多