koa.js yield next 如何运作?

how koa.js yield next works?

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

rowCount 变量在浏览器中打印未定义。但在 connection.query 内部,它会打印所有行。 控制台中的输出也是

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

按照 Koa 中的示例,它应该打印行,然后只打印 D 和 E,但是数据库行在 D 和 E 之后打印。

如果数据库代码被删除,那么它将以正确的顺序打印。我是运行和谐旗

请告诉我问题是什么?

您的 运行 查询与回调异步,这不是您希望在 koa 中执行此操作的方式。

您想使用支持 promise 或 thunk 的库,或者您可以包装您使用的库,使其 return 成为 promise 或 thunk。

然后您将产生查询,它会暂停函数的执行,直到结果为 return,然后函数会从暂停的地方继续执行,并提供可用的查询结果。

对于您的示例,您应该考虑以下库:

我没有用过所以不敢保证,但是一看就觉得合理

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

这个库是 mysql 库的包装器,它是可屈服的。

因此您的代码将如下所示:

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