Javascript Node.js AJAX route在计算引用函数之前返回数据

Javascript Node.js AJAX route在计算引用函数之前返回数据,javascript,ajax,node.js,foursquare,Javascript,Ajax,Node.js,Foursquare,更新 我已经开始工作了,但我还是觉得有问题。只有当我将setTimeout计时器设置为非常长(如2000)时,我才能获得正确的返回数据。如果我将其保留为200,那么回调函数将使用空数据执行,因为API调用尚未返回 我已经更新了下面的代码 设置: 我将通过AJAX(jQuery)从前端发送一个get值,然后使用该值调用foursqaureapi以获取相关场馆的列表 这是工作“好”,除了事件的顺序变得混乱。当我将GET值插入到要计算的函数的参数中时,我得到了一个没有要求的返回值,这会导致模板在给出函

更新

我已经开始工作了,但我还是觉得有问题。只有当我将setTimeout计时器设置为非常长(如2000)时,我才能获得正确的返回数据。如果我将其保留为200,那么回调函数将使用空数据执行,因为API调用尚未返回

我已经更新了下面的代码

设置:

我将通过AJAX(jQuery)从前端发送一个get值,然后使用该值调用foursqaureapi以获取相关场馆的列表

这是工作“好”,除了事件的顺序变得混乱。当我将GET值插入到要计算的函数的参数中时,我得到了一个没有要求的返回值,这会导致模板在给出函数的另一个返回值(我想要的)之前呈现在前端

事实上我不认为它会被退回。刚刚登录到控制台

问题:

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

上下文:

我正在使用此软件包连接到Foursquare:

前端的AJAX调用 index.js[更新] places.js[更新] 当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"}]

您不能仅从内部
findVenue
返回值。对
foursquare.getVinces
的调用是异步的。因此,当节点引擎调用foursquare.getVinces(opt,callback)函数时,它只需启动操作并继续执行任何进一步的语句,然后index.js继续执行,然后呈现响应。。。最后,一段时间后,
foursquare.getVinces
代码调用了它的回调(大概是在与foursquare API完成对话后)

您需要重写
places.findVenue
以获取回调参数。调用
places.findVenue()
时,将向其传递一个要作为回调执行的函数。那是你应该发送回复的时候

下面是一个简化的示例,希望您可以扩展:

function findVenue(opt, callback){
  setTimeout(function(){
    console.log('Done with foursquare.getVenues, calling back to routing function')
    callback(null, opt);   
    // you passs this callback function to setTimeout. it executes it in 200ms
    // by convention, pass a null error object if successful
  }
  ,200);
};


app.get('/return/places', function(req, res){
  console.log('routing function start');
  findVenue({
    lat:40, 
    lng: 70, 
    query: 'foo'
  }, function(err, data){
    console.log('findVenue callback');
    if(err){ return res.send(500) };
    res.render('template', {foo: data});
  });

});

谢谢你的全面回答,我很感激。我今晚会做这件事,让你知道(并接受答案)。谢谢所以我根据你的建议让它工作了,但前提是我把setTimeout定时器设置得很长,比如2000。如果我将其保留为200,则执行回调时不使用Foursquare数据。那意味着我做错了,对吗?我将用新代码更新上面的问题。嘿,我刚才使用了
setTimeout
作为异步函数的示例。直接从
findVenues
调用
foursquare.getVinces()
而不是
setTimeout
可以。只需遵循相同的回调模式,即在传入的回调中放置任何对时间敏感的代码:
foursquare.getVinces(opt,function(err,data){…}
call现在,foursquare的API有可能会在您的计时窗口内响应,设置
jsonUniquePlaces
以便
及时返回回调(null,jsonUniquePlaces);
具有非空值。放置
回调(err,jsonUniquePlaces)
getVinces回调中的代码,而不是
return jsonUniquePlaces
最后,这是我用来理解异步代码设计的链接之一:如果必须将一系列异步操作链接在一起,这个库可能非常有用:
(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);
| 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
| 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"}]
function findVenue(opt, callback){
  setTimeout(function(){
    console.log('Done with foursquare.getVenues, calling back to routing function')
    callback(null, opt);   
    // you passs this callback function to setTimeout. it executes it in 200ms
    // by convention, pass a null error object if successful
  }
  ,200);
};


app.get('/return/places', function(req, res){
  console.log('routing function start');
  findVenue({
    lat:40, 
    lng: 70, 
    query: 'foo'
  }, function(err, data){
    console.log('findVenue callback');
    if(err){ return res.send(500) };
    res.render('template', {foo: data});
  });

});