sails.js node.js 在控制器上解析 JSON

sails.js node.js Parse JSON on controller

在我的名为 MapController 的控制器中,我正在执行一个函数来解析远程 json 文件,并且从 if-else 结构向名为 "parsewebservice" 的数组中添加一些值,显然一切正常,但 console.log ( parsewebservice);没有在返回空的地方返回传递给数组 "parsewebservice" 的值。但是当我把它放在 forEach 里面时 returns,但是一切都变得混乱和重复,这不是正确的方法。

我想知道为什么传递给数组 "parsewebservice" 的值在 populada 之后与变量不一致,正确的方法是什么?

下面是我的代码:

/**
 * MapController
 *
 * @description :: Server-side logic for managing Maps
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {

  index: function(req, res, next) {

    Data.find(function foundData(err, datas) {
      if (err) return next(err);

      var parsewebservice = [];

      datas.forEach(function(data, index) {

        var req = require("request");
        var url = data.address + "?f=pjson";

        req(url, function(err, res, retorno) {
          if (err) {
            console.log(err);
          } else {

            var camadas = JSON.parse(retorno);
            if (camadas.mapName) {

              camadas.layers.forEach(function(campo, i) {

                if (campo.subLayerIds != null) {


                } else if (campo.subLayerIds == null) {
                  parsewebservice.push([i, "dynamicMapLayer", campo.name, data.address]);
                }
              });

            } else if (camadas.serviceDataType) {
              parsewebservice.push([null, "imageMapLayer", camadas.name, data.address]);

            } else if (camadas.type) {
              parsewebservice.push([null, "featureLayer", camadas.name, data.address]);

            }

          }

        });

      });

      console.log(parsewebservice);

    });

  },

};

我的第一条评论是,您不应将 function(req, res)var req = require('request') 结合使用...您将失去对原始 req 对象的访问权限!

因此,您需要 运行 一个异步任务列表,并在它们全部完成时执行一些操作。这永远不会完全容易,无论如何,您都必须习惯这样的想法,即您的代码在编写时从上到下 而不是 运行它。您的 console.log 在您传递给外部请求的任何回调(您传入的函数)之前的底部 运行s。

做到这一点的正确方法是使用承诺。看起来您正在使用 this request library, whose returned requests can only accept callbacks, not be returned as promises. You can create your own promise wrapper for them, or use an alternative library (several are recommended on the page).


我不想在这里写一个完整的 promises 介绍,所以我要做的是给你一个不那么漂亮,但可能更容易理解的方式 运行 完成一些代码你所有的请求。

Data.find(function foundData(err, datas) {
  if (err) return next(err);
  var parsewebservice = [];

  // here we will write some code that we will run once per returned data
  var processResponse = function(resp) {
      parsewebservice.push(resp);
      if(parsewebservice.length >= datas.length) {
        // we are done, that was the final request
        console.log(parsewebservice);
        return res.send({data: parsewebservice)}); // or whatever
      }
  };

  datas.forEach(function(data, index) {
    var request = require("request");
    var url = data.address + "?f=pjson";
    request(url, function(err, res, retorno) {
      // do some processing of retorno...
      // call our function to handle the result
      processResponse(retorno);
    });

  });

  console.log(parsewebservice); // still an empty array here
});    

我解决了问题。

"request" 模块是异步的,所以我们需要等待它响应,然后将响应发送到视图。

为此,我们创建了一个名为 "foo" 的函数来包含 foreach 和请求,我们对该函数进行了回调,最后我们在该函数中进行了响应 (res.view),这样控制器响应只会在 "foo" 函数响应回调之后发送。因此,我们能够使用 foreach 和 "request" 模块 parse.json 来自 "data" 集合的数据,并将对象发送到视图。

非常感谢所有帮助过我的人,由衷的感谢。