简体   繁体   English

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

[英]nodeJS / Express: what's wrong with this RSVP promise?

I'm using nodeJS, running express4 framework to create an API. 我正在使用nodeJS,运行express4框架来创建API。 I am using RSVP.js for promises. 我正在使用RSVP.js进行承诺。

worker.getFamilies is called by an external module, not reflected here. worker.getFamilies由外部模块调用,此处未反映。 The caller expects back an object with results. 调用者希望返回一个带有结果的对象。

Inside worker.getFamilies: - I am querying mongoDB using mongoose (works, we get results back) 在worker.getFamilies内部:-我正在使用mongoose查询mongoDB(可行,我们得到结果)

  • I am using a promise to get the response object from mongoose when its available. 我使用诺言从猫鼬获得响应对象(如果可用)。 That works. 这样可行。

  • Then I try to return JSON.stringify(results); 然后我尝试返回JSON.stringify(results); to the caller of worker.getFamilies and that doesnt work. 给worker.getFamilies的调用者,那是行不通的。 The caller gets back "undefined". 呼叫者返回“未定义”。 please help. 请帮忙。

     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); }); }; 

Well, for starters your worker.getFamilies function doesn't have a single return statement in it so that's why it returns undefined (this is what JavaScript returns automatically if you don't explicitly return). 好吧,对于初学者来说, worker.getFamilies函数中没有单个return语句,这就是为什么它返回undefined的原因(如果您未明确返回,这就是JavaScript自动返回的内容)。

Your only return there is inside the .then handler. 您唯一的返回值在.then处理程序内。 You need to return the promise: 您需要退还诺言:

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);
    });  
};

Now that our function returns, we can use its return value: 现在我们的函数返回了,我们可以使用它的返回值:

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

As Jonathan Lonowski explained, "The result of an asynchronous task can't really be return ed" . 正如乔纳森·洛诺夫斯基(Jonathan Lonowski)解释的那样, “异步任务的结果无法真正return

There are a couple of solutions for this. 有两种解决方案。

If you have control of the code calling worker.getFamilies . 如果您可以控制调用worker.getFamilies的代码。 You can modify the code to: 您可以将代码修改为:

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

The make the calling code do this: 使调用代码执行此操作:

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

If you don't have control over the calling code, it becomes slightly more complicated: 如果您无法控制调用代码,它将变得稍微复杂一些:

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.
});

Basically, you need to make sure the result is ready before calling the code that needs it. 基本上,您需要在调用所需代码之前确保结果已准备就绪。

Problem is you are returning from a different context. 问题是您要从其他上下文返回。 Refactor getFamilies as follows: 重构getFamilies如下:

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

Since there at least one asynchronous function in the call-stack (in your case - getFamiliesFromDb ) you need callbacks (or promises). 由于在调用栈中至少有一个异步函数(在您的情况下为getFamiliesFromDb ),您需要回调(或getFamiliesFromDb )。

In your version, your return statement resolves to the callback function, not getFamilies as you would like to. 在您的版本中,您的return语句解析为回调函数,而不是您想要的getFamilies

Another approach is to transform getFamiliesFromDB to a synchronous call. 另一种方法是将getFamiliesFromDB转换为同步调用。 Either using mongoose API or waiting for the promise to resolve and return it's resolved data. 使用猫鼬API或等待Promise解析并返回其解析数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM