节点js - 如何正确使用模块内的异步网络调用

时间:2015-06-10 13:25:45

标签: javascript json node.js facebook asynchronous

因此,对于我正在开发的项目的一部分,我创建了一个使用Facebook图形API进行调用并返回JSON数据的模块。我可以将console.log()方法中的数据排除在外,这一切都很好。

但是我无法从方法中返回值,所以我尝试使用'async'npm模块。我已经按照网站上的示例进行了操作,但仍然在努力让一切工作正常,到目前为止花了一整天时间,而且事情看起来还不够清楚。

所以我要问的是:

  • 首先,我需要调用为fbgraph api设置authentication_token的方法,然后再做其他事情
  • 然后我需要调用每个函数(按任意顺序)并获取每个函数的json结果并将其添加到一个大的json结果
  • 最后我需要将这个大的json结果重新放回我的原始javascript页面(即使它当前在一个模块中),我将如何调用它?

这是我原始模块的snippit(仅适用于console.log,无法返回)

module.exports = {
        /**
         * Pass the access token to the fbgraph module
         * and call other methods to populate
         */
         setUp: function (access_token) {
             graph.setAccessToken(access_token);
         },

        /**
         * Fetches users basic info:
         * Age, Gender, Hometown, Relationship status
         */
        getBasicInfo: function(){
            graph.get("/me/", function(err, res) {
                var result = {
                    'age'       : _calculateAge(res.birthday),
                    'gender'    : res.gender,
                    'hometown'  : res.hometown.name,
                    'relationship_status' : res.relationship_status
                };
                //console.log(result);
                return result;
            }, function(){ console.log("DONE");});
        },
        /**
         * Creates a body of text as a string
         * made up of all the users status updates
         */
        getPosts: function(){
            graph.get("/me/feed?limit="+PHOTO_LIMIT, function(err, res) {
                var posts = "";
                for(var i=0;i<res.data.length;i++){
                    var obj = res.data[i];
                    if(obj.message!=undefined) posts += obj.message+"\n";
                }
                //console.log(posts);
                return {'posts':posts};
            });
        },
        /**
         * Fetches a single dimension string array of
         * photos user is tagged in
         */
        getPhotos: function(){
            graph.get("/me/photos?limit="+PHOTO_LIMIT, function(err, res) {
                var photos = [];
                for(var i=0;i<res.data.length;i++){
                    var obj = res.data[i];
                    photos.push(obj.source); // .source is full size image, .picture is a thumbnail
                }
                return {'photos': photos};
            });
        }
     }

本单元的其余部分以类似的方式继续 我尝试过使用parralel async

module.exports = {
    getFacebookInfo: function (access_token) {
        results = {};
        setUp(access_token);
        async.parallel([
            facebookDataRequests.getBasicInfo(),
            facebookDataRequests.getPosts()

非常感谢任何有关如何构建此内容的指导,非常感谢

1 个答案:

答案 0 :(得分:1)

我建议你以不同的方式构建它。没有必要对Facebook进行三次调用,因为您也可以在一次通话中获取信息。

所以,我要做的事情:

  1. 使用字段扩展
  2. 调用Facebook Graph API
  3. 格式化结果
  4. 返回结果
  5. 另外,我建议你使用像Q这样的Promise库

    像这样(未经测试!):

    module.exports = {
        getFacebookInfo: function (access_token) {
    
            setUp(access_token);
    
            function setUp(access_token) {
                 graph.setAccessToken(access_token);
             }
    
            function getFBInfo() {
                var deferred = Q.deferred();
                graph.get("/me?fields=id,name,birthday,gender,hometown,relationship_status,feed.limit(25),photos.limit(25)", function(err, res) {
                    if (err) deferred.reject(err);
                    deferred.resolve(res);
                });
                return deferred.promise
            }
    
            function handleResult(result) {
                var deferred = Q.deferred();
    
                result.posts = result.feed.data
                delete result.feed.data;
    
                result.photos = result.photos.data
                delete result.photos.data;
    
                deferred.resolve(result);
    
                return deferred.promise
            }
    
            Q.fcall(getFBInfo)
            .then(handleResult)
            .then(function(result) {
                return result;
            })
            .catch(function (error) {
                // Handle any error from all above steps
            })
            .done();
        }
    }
    

    在您的主文件中:

    var FB = require('./path/to/file/above');
    
    var results = FB.getFacebookInfo('ACCESS_TOKEN_SDAIOFHIOSDHFOSO');