我有一个函数可以从数据库中提取一个来自问题集的随机问题。
Game_Questions.js - 下面的console.log打印出正确的值(我需要的字符串),所以我认为返回会让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)中的question[0].text
函数中访问random_Question
值。到目前为止我尝试过的:
var found_Question = Game_Questions.random_Question();
var found_Question = Game_Questions.random_Question().next().value;
这两个返回[Object object]后使用JSON.stringify()显示该对象是:
{"value":{"emitter":{"domain":null,"_events":{}},"emitted":{},"ended":true},"done":false}
我也试过使用co(function*())
,但它也没让我拿出价值。请帮忙如何访问它?
答案 0 :(得分:2)
@remus的回答是一种回调方法,而Koa是明确设计用于回调回调。因此,虽然它是非常好的代码并且适合Express应用程序,但它与Koa背后的设计理念完全不一致。
从它的外观来看,你使用的Mongoose支持自4.0版(2015年4月发布)以来的异步操作的承诺,这应该允许采用收益方法。注意我假设您正在使用Mongoose - 我希望我没错!
Here is some nice documentation on how Mongoose would fit nicely with koa.
首先,请确保您使用支持使用yield的Mongoose版本。如果不是,您将不得不使用@remus方法或手动包装您的每个方法,以便它们兼容(即使用promises包装)。
但是,如果您使用的是兼容版本(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应用程序流控制的co
产生 - 检查tj/co on GitHub以获取可以产生的不同对象。
所以最后回到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);
上述代码片段之一。所以我们这样做:
findRandom
需要注意的是,我对mongoose查询中的yield
方法有点不确定,因为我不知道它是否与mongoose的Promise功能很好地配合。我个人会在重新引入findRandom
之前使用tessedit_write_images
获得正常的猫鼬查询,以确保它不会导致问题。
我的答案在这一点上变得有点长,所以我会把它留在那里。