繁体   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