0

这是我的第一个 JavaScript 和 Node 项目,我被卡住了……

我正在尝试调用一个返回一组 Post ID 的 REST API ......并基于一组检索到的 ID 我试图调用另一个 API,该 API 从第一个 API 返回每个 ID 的详细信息。该代码使用 Facebook-NodeSDK 提供的 Facebook API。

我遇到的问题是第二个 API 在 FOR 循环中触发……。据我了解,for循环异步执行每个请求……。我可以看到两个查询都在执行,但是我不知道如何捕获第二个 for 循环的结尾以将最终结果返回给用户……</p>

以下是代码……</p>

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)......。并尝试在多个地方调用它,但无法获取所有帖子……我已从上面的代码中删除了控制台语句……这表明正在检索数据……

非常感谢您的帮助和关注......

4

2 回答 2

0

如果您只是将 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

希望这可以帮助。

于 2014-03-02T00:23:10.130 回答
0

本质上,您希望map为每个 id 执行异步操作。

有一个非常方便的库可以对集合进行异步操作,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在您的项目目录中运行,您就可以开始了。

于 2014-03-02T02:35:26.457 回答