nodeJS / Express:这个RSVP承诺有什么问题?

时间:2014-08-20 18:09:29

标签: javascript node.js express promise rsvp.js

我正在使用nodeJS,运行express4框架来创建API。我使用RSVP.js作为承诺。

worker.getFamilies由外部模块调用,此处未反映出来。调用者期望返回一个包含结果的对象。

在worker.getFamilies中: - 我使用mongoose查询mongoDB(工作,我们得到结果)

  • 我正在使用一个承诺,当它可用时从mongoose获取响应对象。这样可行。

  • 然后我尝试返回JSON.stringify(results);到worker.getFamilies的调用者,那不起作用。调用者返回“未定义”。请帮忙。

    var worker = exports;
    var RSVP = require('rsvp');
    
    var getFamiliesFromDB = function(DBconnection){
        var promise = new RSVP.Promise(function(resolve, reject){
            DBconnection.find({} ,{limit:10, sort: [['_id',-1]]}).toArray(function(e, results){ 
                console.log('results:', results);
                resolve(results);
            });   
        });
        return promise;
    }
    
    worker.getFamilies = function(DBConnection){
        getFamiliesFromDB(DBConnection).then(function(results){
    
            //this works
            console.log('here are the fams from the promise', results);
    
            //this doesnt work like i want it to
            return JSON.stringify(results);
        });  
    };
    

3 个答案:

答案 0 :(得分:2)

好吧,对于初学者来说,你的worker.getFamilies函数中没有一个return语句,这就是它返回undefined的原因(如果你没有,这就是JavaScript自动返回的内容)明确地返回)。

你唯一的回复是在.then处理程序内。你需要回复承诺:

worker.getFamilies = function(DBConnection){
    // note how we've added a `return` here!
    return getFamiliesFromDB(DBConnection).then(function(results){
        console.log('here are the fams from the promise', results);
        return JSON.stringify(results);
    });  
};

现在我们的函数返回了,我们可以使用它的返回值:

// from caller site:
worker.getFamilies(dbconn).then(function(jsonResults){
    console.log("Got results!", jsonResults);
});

答案 1 :(得分:1)

Jonathan Lonowski解释说,"The result of an asynchronous task can't really be returned"

有几个解决方案。

如果您可以控制调用worker.getFamilies的代码。您可以将代码修改为:

worker.getFamilies = function(DBConnection){
    return getFamiliesFromDB(DBConnection).then(function(results) {
        return JSON.stringify(results);
    });  
};

使调用代码执行此操作:

worker.getFamilies(DBConnection).then(function(results) {
  console.log('now I can work with', results);
});

如果您无法控制调用代码,则会变得稍微复杂一些:

var data;
worker.getFamilies = function() {
    return data;
};
getFamiliesFromDB(DBConnection).then(function(results) {
        data = JSON.stringify(results);
        // Here, start up the code where `worker.getFamilies` is used.
});

基本上,在调用需要它的代码之前,您需要确保结果已准备就绪。

答案 2 :(得分:0)

问题是你是从不同的背景回来的。重构getFamilies如下:

worker.getFamilies = function(DBConnection, callback){
    getFamiliesFromDB(DBConnection).then(function(results){
        callback(JSON.stringify(results));
    });  
};

由于调用堆栈中至少有一个异步函数(在您的情况下为getFamiliesFromDb),您需要回调(或承诺)。

在您的版本中,您的return语句会解析为回调函数,而不是您想要的getFamilies

另一种方法是将getFamiliesFromDB转换为同步调用。使用mongoose API或等待承诺解析并返回其已解析的数据。