获取生成器函数的值,koa
Getting value of generator function, koa
我有一个函数可以从数据库中提取问题集合中的随机问题。
Game_Questions.js - 下面的 console.log 打印出正确的值(我需要的字符串),所以我认为 return 会让 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;
那两个 return [Object object] 在使用 JSON.stringify() 后显示该对象是:
{"value":{"emitter":{"domain":null,"_events":{}},"emitted":{},"ended":true},"done":false}
我也试过使用co(function*())
,但它也没有让我取出值。请帮助如何访问它?
您的语法很奇怪,但不确定这是否是 Koa 特有的?
因为Node.js是基于事件的,所以改用回调:
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
.
@remus 的答案是回调方法,而 Koa 被明确设计为放弃回调。因此,尽管它是非常好的代码并且适合 Express 应用程序,但它与 Koa 背后的设计理念完全不一致。
从外观上看,您使用的是 Mongoose,它从 4.0 版(2015 年 4 月发布)开始支持异步操作的承诺,应该允许采用 yield 方法。请注意,我假设您正在使用 Mongoose - 希望我没有错!
Here is some nice documentation on how Mongoose would fit nicely with 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;
}
请注意,我假设结果是一个基于您提供的代码的数组。
上面的例子不一定是生成器函数。 returns 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);
还有一点要注意,我对 mongoose 查询中的 findRandom
方法有点不确定,因为我不知道它是否能很好地与 mongoose 的 Promise 功能配合使用。就我个人而言,在重新引入 findRandom
之前,我会使用 yield
进行正常的猫鼬查询,只是为了确保它不会引起问题。
我的回答现在有点长,所以我就到此为止。
我有一个函数可以从数据库中提取问题集合中的随机问题。
Game_Questions.js - 下面的 console.log 打印出正确的值(我需要的字符串),所以我认为 return 会让 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;
那两个 return [Object object] 在使用 JSON.stringify() 后显示该对象是:
{"value":{"emitter":{"domain":null,"_events":{}},"emitted":{},"ended":true},"done":false}
我也试过使用co(function*())
,但它也没有让我取出值。请帮助如何访问它?
您的语法很奇怪,但不确定这是否是 Koa 特有的?
因为Node.js是基于事件的,所以改用回调:
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
.
@remus 的答案是回调方法,而 Koa 被明确设计为放弃回调。因此,尽管它是非常好的代码并且适合 Express 应用程序,但它与 Koa 背后的设计理念完全不一致。
从外观上看,您使用的是 Mongoose,它从 4.0 版(2015 年 4 月发布)开始支持异步操作的承诺,应该允许采用 yield 方法。请注意,我假设您正在使用 Mongoose - 希望我没有错!
Here is some nice documentation on how Mongoose would fit nicely with 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;
}
请注意,我假设结果是一个基于您提供的代码的数组。
上面的例子不一定是生成器函数。 returns 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);
还有一点要注意,我对 mongoose 查询中的 findRandom
方法有点不确定,因为我不知道它是否能很好地与 mongoose 的 Promise 功能配合使用。就我个人而言,在重新引入 findRandom
之前,我会使用 yield
进行正常的猫鼬查询,只是为了确保它不会引起问题。
我的回答现在有点长,所以我就到此为止。