获得发电机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
。