nodejs 同步问题与 q

nodejs sync issue with q

我用http get 获取了一个json,但是不能把它传递到首页,即使我已经使用了q,有用的是可以执行同步,但仍然有问题,有人可以帮忙吗? //getturnto.js

    var conf = require("../conf/setting.json");
    var http = require("http");

    function TurnToUGC(){
        if(!(this instanceof TurnToUGC)){
            return new TurnToUGC();
        }
    };

    TurnToUGC.prototype.getUGCJson = function(item,callback){            
        var UGCPath = conf.UGCPath;
        var options = {
            host:conf.UGCHost,
            port:conf.UGCPort,
            path:UGCPath
        };
        http.get(options,function(res){
            var buf = "";
            res.on("data",function(d){
                buf += d;
            });
            res.on("error",function(error){
                callback(error);
            });
            res.on("end", function () {
                var ret;
                try{
                    ret = JSON.parse(buf);
                }catch (err){
                    return callback(err);
                }
                callback(null,ret);
            })
        }).on("error",function(er){
            console.log(er);
        });
    };
    module.exports = TurnToUGC;

然后我想展示它,(我用express生成了一个简单的网页) //这是router.index

    var q = require("q");
    exports.index = function(req, res,next){
        var getturnto = require("getturnto")();
        q().then(function(){
            getturnto.getUGCJson(null,function(err,re){
                if(err){
                    console.log(err);
                    return {"error":err};
                }else {
                    console.log(re);
                    return re;
                }
            });
        })
            .then(function(UGCData){
                res.render('index',
                    { title: 'Get UGC Content',
                        data:UGCData
                    }
                );
            })
            .fail(function(err){
                console.log(err);
                next(err);
            });
    }

json可以在控制台打印出来,但是"UGCData"总是undefined,json对象不能传递到首页。

请阅读承诺的传播here。由于您的 getturnto.getUGCJson 是异步的,因此您的第一个输出处理程序是 returning undefined。这就是您在 UGCData 中变得不确定的原因。您需要做的是 return 第一个输出处理程序中的承诺。试试这个方法:

var q = require("q");
exports.index = function(req, res,next){
    var getturnto = require("getturnto")();
    q().then(function(){
        var deferred = q.defer();
        getturnto.getUGCJson(null,function(err,re){
            if(err){
                console.log(err);
                deferred.reject(new Error(error));
            }else {
                console.log(re);
                deferred.resolve(re);
            }
        });
        return deferred.promise;
    })
        .then(function(UGCData){
            res.render('index',
                { title: 'Get UGC Content',
                    data:UGCData
                }
            );
        })
        .fail(function(err){
            console.log(err);
            next(err);
        });
}

如果您将 getUGCJson 重写为 return 承诺会更好。

最终版本: 1.getturnto.js

.....

    TurnToUGC.prototype.getUGCJson = function(){         

        *var deferred = q.defer();*

        http.get(options,function(res){
            ....
            res.on("error",function(error){
                *deferred.reject(new Error(error))*;
            });
            res.on("end", function () {
                try{
                    *deferred.resolve(JSON.parse(buf));*
                }catch (err){
                    console.log(err);
                }
            })
        }).on("error",function(er){
            console.log(er);
        });
        *return deferred.promise;*
    };

    module.exports = TurnToUGC;

2.router

     getturnto.getUGCJson(null).then(function(UGCData){
            res.render('index',
                { title: 'Get UGC Content',
                    data:UGCData,
                    comments:UGCData.comments,
                    questions:UGCData.questions
                }
            );
    })
    .fail(function(err){
        console.log(err);
        next(err);
    });
    }