[英]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.