簡體   English   中英

如何使用Node JS中的嵌套/相關API調用從FOR循環結束時捕獲結果

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM