Javascript Node.js AJAX route在计算引用函数之前返回数据
更新 我已经开始工作了,但我还是觉得有问题。只有当我将setTimeout计时器设置为非常长(如2000)时,我才能获得正确的返回数据。如果我将其保留为200,那么回调函数将使用空数据执行,因为API调用尚未返回 我已经更新了下面的代码 设置: 我将通过AJAX(jQuery)从前端发送一个get值,然后使用该值调用foursqaureapi以获取相关场馆的列表 这是工作“好”,除了事件的顺序变得混乱。当我将GET值插入到要计算的函数的参数中时,我得到了一个没有要求的返回值,这会导致模板在给出函数的另一个返回值(我想要的)之前呈现在前端 事实上我不认为它会被退回。刚刚登录到控制台 问题: 如何通过AJAX将places.js中initGetVinces函数末尾的JSON对象过滤列表返回到前端 上下文: 我正在使用此软件包连接到Foursquare: 前端的AJAX调用 index.js[更新] places.js[更新] 当setTimeout为200时,我得到:Javascript Node.js AJAX route在计算引用函数之前返回数据,javascript,ajax,node.js,foursquare,Javascript,Ajax,Node.js,Foursquare,更新 我已经开始工作了,但我还是觉得有问题。只有当我将setTimeout计时器设置为非常长(如2000)时,我才能获得正确的返回数据。如果我将其保留为200,那么回调函数将使用空数据执行,因为API调用尚未返回 我已经更新了下面的代码 设置: 我将通过AJAX(jQuery)从前端发送一个get值,然后使用该值调用foursqaureapi以获取相关场馆的列表 这是工作“好”,除了事件的顺序变得混乱。当我将GET值插入到要计算的函数的参数中时,我得到了一个没有要求的返回值,这会导致模板在给出函
| 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});
});
});