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

UPDATE

得到它的工作,但我仍然认为有一个问题。 如果将setTimeout计时器设置为非常长(如2000),则只会得到正确的返回数据。如果将其保留为200,则由于API调用尚未返回,因此callback函数将以空数据执行。

我已经更新了下面的代码。

build立:

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

这是工作“罚款”,除了事件的顺序变得棘手。 当我将GET值插入到函数的参数中进行求值时,我得到一个我没有要求的返回值,然后导致模板在我函数的另一个返回值之前在前端呈现 -给我一个我想要的。

而实际上我不认为它实际上正在退回。 刚刚login到控制台。

题:

我怎样才能通过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"}] 

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

您需要重写places.findVenue来获取callback参数。 当你调用places.findVenue()你会传递一个函数来执行callback。 是当你应该发送回应。

这是一个简单的例子,你可以希望延伸:

 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}); }); });