Getting value of generator function, koa Getting value of generator function, koa mongoose mongoose

Getting value of generator function, koa


The answer by @remus is a callback approach and Koa was designed explicitly to ditch callbacks. So while it's perfectly good code and would fit an Express application it is completely at odds with the design philosophy behind Koa.

From the looks of it you are using Mongoose which has supported promises for async operations since version 4.0 (which was released Apr 2015) which should allow a yield approach to be taken. Note I'm making an assumption you are working with Mongoose - I hope I'm not wrong!

Here is some nice documentation on how Mongoose would fit nicely with koa.

So first of all make sure you are using a version of Mongoose that supports using yield. If not you'll have to use the @remus approach or manually wrap each of your methods so they are yield compatible (i.e. wrapping with promises).

But if you are using a compatible version (4.0 and upwards) then your code would look something like the following:

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;}

Note that I'm assuming the result is an array based on the code you supplied.

The above example doesn't necessarily have to be a generator function. It could also be a normal function that returns a Promise. So alternatively something like this could also be done:

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;    });}

So for the randomQuestion function all that is important is that it can be yielded by co which handles the Koa application flow control – check tj/co on GitHub for the different objects you can yield.

So finally getting back to the Koa Middleware we can yield either of the above code snippets in the exact same manner. So we'd do:

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);

Something else to note is that I'm a little unsure of the findRandom method in the mongoose query since I don't know if it plays nicely with the Promise features of mongoose. Personally I'd get a normal mongoose query working using yield before reintroducing findRandom just to make sure it's not causing an issue.

My answer is getting a bit long at this point so I'll leave it at that.


Your syntax is pretty strange, but not sure if that's specific to Koa or not?

Because Node.js is event based, use a callback instead:

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

And use it:

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

Of some concern as well is your question states you're trying to reference Game_Questions.randomQuestion() when your function is actually named random_Question.