node-sqlite3与iojs,koa和yield

时间:2015-04-11 20:06:17

标签: node.js sqlite koa

我是iojs的新手,正在尝试使用koa和node-sqlite3编写一个小型Web应用程序。

我无法理解的一件事是如何在基于node-sqlite3回调的API上使用'yield'语法。

我已经用Google搜索了,我发现的是这个stackoverflow帖子(synchronous sqlite transactions node),这说明这是可能的。

任何人都可以给我一个更具体的例子吗?

提前致谢

3 个答案:

答案 0 :(得分:2)

经过多次挖掘后,我在stackoverflow帖子Koa.js request with promises is hanging中找到了一些提示。

诀窍是使用原生的Promises。

以下示例代码适用于iojs v1.6.4和Koa 0.19.0

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

var route = require('koa-route');

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:');

function *query() {
  var promise = new Promise(function(resolve, reject) {
    var result = [];

    db.serialize(function() {
      db.run("DROP TABLE IF EXISTS lorem");
      db.run("CREATE TABLE lorem (info TEXT)");

      var stmt = db.prepare("INSERT INTO lorem VALUES (?)");

      for (var i = 0; i < 10; i++) {
          stmt.run("Ipsum " + i);
      }

      stmt.finalize();

      db.all("SELECT rowid AS id, info FROM lorem", function(err, rows) {
        resolve(rows);
      });
    });
  });

  return promise;
}

function *handler() {
  this.body = yield query();
  this.status = 200;
}

app.use(route.get('/list', handler));

app.listen(3000);

答案 1 :(得分:2)

这里有一个名为co-sqlite3的nodejs模块: https://www.npmjs.com/package/co-sqlite3

基于promise-sqlite3的promise for co或sqlite3 for co或koa

<强>安装

npm install co-sqlite3

<强>用法

  1. 与co合作

    var co = require('co');
    var sqlite3 = require('co-sqlite3');
    
    co(function*() {
    
    //connect a database
    
    var db = yield sqlite3('test.db');
    
    // create a table 
    yield db.run('CREATE TABLE IF NOT EXISTS testtable (id INT NOT NULL)');
    
    var stmt = yield db.prepare('INSERT INTO testtable(id) VALUES( ? )');
    
    for(var i =0 ; i < 100 ; i++){
        yield stmt.run(i);
    }
    
    stmt.finalize();
    
    var row = yield db.get('SELECT * FROM testtable WHERE id < ? ORDER BY ID DESC ' ,[50]); 
    console.log(row); // {id: 49}
    
    var rows = yield db.all('SELECT * FROM testtable');
    console.log(rows.length);
    
    
     }).catch(function(err) {
    
    console.log(err.stack);
    
    });
    
  2. 与koa合作

    var koa = require('koa');
    var sqlite3 = require('co-sqlite3');
    
    var app = koa();
    
    app.use(function*(next){
        this.db = yield sqlite3('test.db');
        yield next ;
    });
    
    
    app.use(function* (){
        this.body = yield this.db.get('SELECT * FROM testtable WHERE id < ? ORDER BY ID DESC ' ,[50]);
    })
    
    app.listen(3000);
    
  3. 就像承诺一样

    var sqlite3 = require('co-sqlite3');
    
    
    sqlite3('test.db').then(function(db){
        db.get('SELECT * FROM testtable WHERE id < ? ORDER BY ID DESC ' ,[50])
          .then(function(row){
          console.log(row);
        });
    });
    

答案 2 :(得分:1)

虽然承诺有效,但使用koa的主要优点是利用生成器(yield关键字)。为此,您使用的库需要准备好与生成器一起使用。

我知道您已经指定您使用sqlite,但是对于使用yield进行数据库访问的示例,请参阅此mongodb包co-monk如何工作:

yield users.insert({ name: 'Tobi', species: 'ferret' });

var res = yield users.findOne({ name: 'Tobi' });
res.name.should.equal('Tobi');

虽然您可以自己使用co package包装node-sqlite3,但如果您开始使用,则可能会发现使用其中一个基于co的现有库更容易

似乎还有MySQL的生成器就绪包,但我找不到sqlite的任何等价物。

如果有帮助,这里有一篇更完整的博客文章,其中包含使用合作僧侣的例子:http://www.marcusoft.net/2014/04/koaExamples.html