Node.js AJAX路由在评估引用函数之前返回数据

时间:2013-07-18 06:40:11

标签: javascript ajax node.js foursquare

更新

让它工作,但我仍然认为有问题。如果我将setTimeout计时器设置为非常长,我只得到正确的返回数据,如2000.如果我将它保留为200,那么回调函数将使用空数据执行,因为尚未返回API调用。

我已经更新了以下代码。

设定:

我通过AJAX(jQuery)从前端发送一个get值,然后使用该值调用Foursqaure API来获取相关场所的列表。

除了事件的顺序变得棘手之外,这是“很好”。当我将GET值插入到要评估的函数的参数中时,我得到一个返回值,我要求,然后导致模板在前端渲染之前我的函数的其他返回值 - 我想要的 - 给出了。

实际上我认为它实际上并没有被退回。刚刚登录到控制台。

问题:

如何通过AJAX将places.js中initGetVenues函数末尾的JSON对象的筛选列表返回到前端?

上下文

我正在使用此软件包连接到Foursquare: https://npmjs.org/package/foursquarevenues

前端的AJAX调用

    $("#search-items").submit(function() {
        var placeQuery = $("#search-input").val();

        $.ajax({
            url: '/return/places/',
            data: {"passPlaceQuery": placeQuery},
            type: 'get',
            dataType: 'html',
            success: function(data) {
                $("#search-results-list").html(data);
            },
        });

        return false;
    });

index.js [已更新]

returnPlaces: function(req, res) {
  if (req.headers['x-requested-with'] === 'XMLHttpRequest') {
    console.log("I've started routing");

    return places.findVenue({
      ll: "38.214986,-85.637054",
      radius: 32186,
      query: req.query.passPlaceQuery,
      intent: "browse",
      categoryId: "4bf58dd8d48988d1e0931735"
    }, function(err, data) {
      console.log("Venue callback");

      if (err) {
        res.send(500);
      }

      console.log("Attempting render: " + data);
      return res.render("place-results", {
        layout: false,
        foundPlaces: data
      });

    });
  } else {
    return res.redirect("/");
  }
}

places.js [已更新]

(function() {
  var foursquare, initGetVenues;

  foursquare = (require('foursquarevenues'))('SECRET', 'SECRET');

  module.exports = {
    findVenue: initGetVenues = function(criteria, callback) {
      var jsonUniquePlaces;
      jsonUniquePlaces = [];

      foursquare.getVenues(criteria, function(error, venues) {
        var i, objUniquePlace, range, uniquePlaces, venueName;

        if (!error) {
          range = Object.keys(venues.response.venues).length;
          uniquePlaces = [];
          i = 0;
          while (i < range) {
            venueName = venues.response.venues[i].name;
            if (!(uniquePlaces.indexOf(venueName) > -1)) {
              uniquePlaces.push(venueName);
            }
            i++;
          }
          i = 0;
          while (i < uniquePlaces.length) {
            objUniquePlace = {
              place: uniquePlaces[i]
            };
            jsonUniquePlaces.push(objUniquePlace);
            i++;
          }
          jsonUniquePlaces = JSON.stringify(jsonUniquePlaces);

          return jsonUniquePlaces;
        }
      });

      return setTimeout((function() {
        return callback(null, jsonUniquePlaces);
      }), 200);
    }
  };

}).call(this);

当setTimeout为2000时,我得到:

| I've started routing
| [{"place":"Quills Coffee"},{"place":"Quills Coffe"},{"place":"Quill's Coffee"}]
| Venue callback
| Attempting render: [{"place":"Quills Coffee"},{"place":"Quills Coffe"},{"place":"Quill's Coffee"}]
| GET /return/places/?passPlaceQuery=quills 200 2009ms - 150

当setTimeout为200时,我得到:

| I've started routing
| Venue callback
| Attempting render: 
| GET /return/places/?passPlaceQuery=quills 200 210ms - 11
| [{"place":"Quills Coffee"},{"place":"Quills Coffe"},{"place":"Quill's Coffee"}]

1 个答案:

答案 0 :(得分:2)

您不能只从findVenue内部返回您的值。对foursquare.getVenues的调用是异步的。所以当节点引擎进入函数调用foursquare.getVenues(opt, callback)时,它只是启动操作并继续执行任何进一步的语句,然后index.js继续执行,然后你呈现一个响应......最后一段时间之后,{{ 1}}代码调用它的回调(大概是当它与foursquare API交谈时。)

您需要重写foursquare.getVenues以获取回调参数。当你调用places.findVenue时,你会传递一个函数来执行回调。 是您应该发送回复的时间。

以下是您可以扩展的简化示例:

places.findVenue()