获得发电机function的价值,koa

我有一个函数从数据库中抽出一个来自Questions集合的随机问题。

Game_Questions.js – 下面的console.log输出正确的值(我需要的string),所以我认为返回将让yield返回相同的值。

exports.random_Question = function *() { yield Questions.findRandom().limit(1).exec(function(err,question){ console.log("rand q: " + question[0].text); return question[0].text; }); } 

Game.js:

 var Game_Questions = require('./backend/Game_Questions'); 

在这里我想从上面的代码片段(Game_Questions.js)的random_Question函数访问question[0].text值。 我到目前为止所尝试的是:

var found_Question = Game_Questions.random_Question();

var found_Question = Game_Questions.random_Question().next().value;

这两个返回使用JSON.stringify()后的[Object object]显示对象是: {"value":{"emitter":{"domain":null,"_events":{}},"emitted":{},"ended":true},"done":false}

我也尝试使用co(function*())但它也不让我拿出价值。 请帮助如何访问它?

@remus的回答是一个callback方法,Koa是明确devise的,以消除callback。 所以虽然它是完美的代码,并且适用于Express应用程序,但完全不符合Koa背后的devise理念。

从它的外观来看,您使用的Mongoose支持从4.0版本(2015年4月发布)开始的asynchronous操作的承诺,这应该允许采取收益方法。 注意我正在做一个与mongoose一起工作的假设 – 我希望我没有错!

这里有一些关于Mongoose如何与koa很好地配合的很好的文档。

所以首先确保你使用的是一个支持使用yield的Mongoose版本。 如果没有,你将不得不使用@remus的方法或手动包装你的每个方法,使他们是屈服兼容(即承诺包装)。

但是,如果您使用的是兼容版本(4.0及更高版本),那么您的代码如下所示:

 exports.random_Question = function *() { var result; try { result = yield Questions.findRandom().limit(1).exec(); } catch(e) { console.log(e.stack); throw e; } console.log("rand q: " + result[0].text); return result[0].text; } 

请注意,我假设结果是一个基于您提供的代码的数组。

上面的例子不一定是一个生成器函数。 这也可能是一个正常的函数返回一个Promise。 所以也可以这样做:

 exports.random_Question = function() { return Questions.findRandom() .limit(1) .exec() .then(function() { // I'm assuming mongoose assigns the value // being resolved in exec() to 'this' var question = this[0]; console.log("rand q: " + question.text); return question.text; }).catch(function(e) { console.log(e.stack); throw e; }); } 

所以对于randomQuestion函数来说,所有重要的是它可以由处理Koa应用程序stream控制的co产生 – 在GitHub上检查你可以产生的不同对象的tj / co 。

所以最后回到Koa中间件,我们可以以完全相同的方式yield上面的代码片段。 所以我们会这样做:

 var koa = require("koa"); var app = module.exports = koa(); var Game_Questions = require('./backend/Game_Questions'); app.use(function*() { var resultText; try { resultText = yield Game_Questions.random_Question(); } catch(e) { this.throw(500); } this.body = resultText; this.status = 200; }); app.listen(3000); 

还有一点需要注意的是,我对于mongoose查询中的findRandom方法有些不确定,因为我不知道它是否和mongoose的Promise特性很好地搭配。 就个人而言,我会得到一个正常的mongoose查询工作使用yield之前重新引入findRandom只是为了确保它不会造成问题。

我的回答在这一点上已经有点长了,所以我会留下来的。

你的语法很奇怪,但不确定这是否特定于Koa?

由于Node.js是基于事件的,因此请使用callback:

 exports.random_Question = function(callback) { Questions.findRandom().limit(1).exec(function(err, question){ callback(err, question); }); } 

并使用它:

 var Game_Questions = require('./backend/Game_Questions'); Game_Questions.random_Question(function(err, question) { console.log(question); }); 

还有一些问题是你的问题表明你试图引用Game_Questions.randomQuestion()当你的函数实际上被命名为random_Question