J.Krishna
J.Krishna

Reputation: 1010

how koa.js yield next works?

I have the following code in koa.js

var koa = require('koa');
var app = koa();
var mysql = require('mysql');

app.use(function *(next) {
  console.log('A');
  yield next;
  console.log('E');
});

app.use(function *(next) {
  console.log('B');
  yield next;
  console.log('D');
});

app.use(function *(next) {
var rowCount;
  console.log('C');
  var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : 'pass',
    database : 'db1'
  });

  connection.connect();

  connection.query('SELECT * from itemcategory', function(err, rows, fields) {
    if (err) throw err;

    console.log('The solution is: ', rows);
    rowCount = rows;
    console.log('The rowCount is: ', rowCount);
  });


  this.body = "we are good!.." + rowCount ;
  connection.end();

});

app.listen(3000);

The rowCount variable prints undefined in the browser. But inside the connection.query it prints all the rows. Also the output in the console is

PS J:\proj\pg> node --harmony  .\app.js
A
B
C
D
E
The solution is:  [ { categoryno: 0, categoryname: 'PESTICIDES', categorystatus: 0 },
  { categoryno: 1, categoryname: 'SEEDS ', categorystatus: 0 },
  { categoryno: 2, categoryname: 'FERTILIZERS', categorystatus: 0 },
  { categoryno: 3, categoryname: 'OTHERS', categorystatus: 0 } ]
The rowCount is:  [ { categoryno: 0, categoryname: 'PESTICIDES', categorystatus: 0 },
  { categoryno: 1, categoryname: 'SEEDS ', categorystatus: 0 },
  { categoryno: 2, categoryname: 'FERTILIZERS', categorystatus: 0 },
  { categoryno: 3, categoryname: 'OTHERS', categorystatus: 0 } ]

As per the example in Koa it should print the rows and then only D and E, but the db rows are printed after D and E.

If the db code is removed then it prints in the correct order. I am running with harmony flag.

Please tell me what is the problem?

Upvotes: 0

Views: 1269

Answers (1)

James Moore
James Moore

Reputation: 1901

Your running the query asynchronously with a callback, which isn't the way you would want to do this in koa.

You want to either use a library that supports promises or thunks or you can wrap the library your using so that it returns a promise or a thunk.

Then you would yield the query, which pauses the execution of the function until a result is return, then the function continues from where it was paused with the result of the query available.

For your example you should consider the following library:

I haven't used it so I can't vouch for it, but it looks reasonable at a glance.

https://github.com/sidorares/mysql-co

This library is a wrapper over the mysql library that is yield-able.

So your code would look like this:

var koa = require('koa');
var app = koa();
var mysql = require('mysql-co');

app.use(function *(next) {
  console.log('A');
  yield next;
  console.log('E');
});

app.use(function *(next) {
  console.log('B');
  yield next;
  console.log('D');
});

app.use(function *(next) {
var rowCount;
  console.log('C');
  try{
    var connection = mysql.createConnection({
      host     : 'localhost',
      user     : 'root',
      password : 'pass',
      database : 'db1'
    });

    var result = yield connection.query('SELECT * from itemcategory');
    console.log(result);

    this.body = "we are good!.." + result.rows ;
    connection.end();
  }
  catch(err){
    // handle any errors here
  }
});

app.listen(3000);

Upvotes: 2

Related Questions