获得发电机功能的价值,koa

时间:2015-07-22 03:50:06

标签: javascript node.js mongoose koa

我有一个函数可以从数据库中提取一个来自问题集的随机问题。

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*()),但它也没让我拿出价值。请帮忙如何访问它?

1 个答案:

答案 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获得正常的猫鼬查询,以确保它不会导致问题。

我的答案在这一点上变得有点长,所以我会把它留在那里。

相关问题