[英]How to capture results from end of FOR loop with Nested/Dependent APIs calls in Node JS
这是我的第一个JavaScript&Node项目,我被困住了。
我试图调用一个REST API,该REST API返回一组帖子ID ...,并基于检索到的ID集,我试图调用另一个API,该API从第一个API返回每个ID的详细信息。 该代码使用Facebook-NodeSDK提供的Facebook API。
我遇到的问题是在FOR循环中触发了第二个API。 据我了解,for循环异步执行每个请求……。 我可以看到两个查询都在执行,但是我无法弄清楚如何捕获第二个for循环的末尾以将最终结果返回给用户……
以下是代码…
exports.getFeeds = function(req, res) {
var posts = [];
FB.setAccessToken(’SOME TOKEN');
var resultLength = 0;
FB.api(
//ARG #1 FQL Statement
'fql', { q: 'SELECT post_id FROM stream WHERE filter_key = "others"' },
//ARG #2 passing argument as a anonymous function with parameter result
function (result)
{
if(!result || result.error) {
console.log(!result ? 'error occurred' : result.error);
return;
} //closing if handling error in this block
var feedObj
console.log(result.data);
console.log(result.data.length);
for (var i = 0; i<resultLengthj ; i++) {
(function(i) {
feedObj = {};
FB.api( result.data[ i].post_id, { fields: ['name', 'description', 'full_picture' ] },
// fbPost is data returned by query
function (fbPost) {
if(!fbPost || fbPost.error) {
console.log(!fbPost ? 'error occurred' : result.error);
return;
}
// else
feedObj=fbPost;
posts.push(feedObj);
});
})(i);
}// end for
}//CLOSE ARG#2 Function
);// close FB.api Function
注意我需要打电话给...... res.Send(post)...。 并尝试在多个位置调用它,但无法获取所有帖子……我从上面的代码中删除了控制台语句……这表明正在检索数据……
非常感谢您的帮助和关注。
如果您只在代码中的几乎任何位置粘贴res.send,那么一定会在帖子返回之前被调用。
在这种情况下,您要做的是在for循环外声明一个计数器变量并将其设置为零。 然后在for循环中增加它。 然后在内部回调中(对于您的情况,每个帖子被调用一次),您将减少计数器并测试计数器何时为零。 下面,我将该技术应用于您的代码的编辑版本(我看不到feedObj实际在做什么,也不了解您为什么使用立即调用的函数,因此消除了两者-请让我知道是否错过了一些事情那里)。
var posts = [];
FB.setAccessToken(’SOME TOKEN');
var resultLength = 0;
FB.api(
//ARG #1 FQL Statement
'fql', { q: 'SELECT post_id FROM stream WHERE filter_key = "others"' },
//ARG #2 passing argument as a anonymous function with parameter result
function (result)
{
if(!result || result.error) {
return;
} //closing if handling error in this block
var counter = 0;
for (var i = 0; i<resultLengthj ; i++) {
counter++;
FB.api( result.data[ i].post_id, { fields: ['name', 'description', 'full_picture' ] },
function (fbPost) { // fbPost is data returned by query
if(!fbPost || fbPost.error) {
return;
}
posts.push(fbPost);
counter--;
if (counter === 0){
// Let's render that page/send that result, etc
}
});
}// end for
}//CLOSE ARG#2 Function
);// close FB.api Function
希望这可以帮助。
本质上,您想对每个id进行异步map
操作。
有一个非常方便的库,用于对名为async
集合执行异步操作,该库具有async.map
方法。
var async = require('async');
FB.api(
'fql', { q: 'SELECT post_id FROM stream WHERE filter_key = "others"' },
//ARG #2 passing argument as a anonymous function with parameter result
function (result) {
async.map(
result,
function (item, callback) {
FB.api(
item.post_id,
{ fields: ['name', 'description', 'full_picture' ] },
callback
);
},
function (err, allPosts) {
if (err) return console.log(err);
// Array of all posts
console.log(allPosts);
}
);
}
);
您绝对不需要使用它,但是它可以稍微简化您的代码。 只需运行npm install --save async
在项目目录中保存npm install --save async
,就可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.