我是iojs的新手,正在尝试使用koa和node-sqlite3编写一个小型Web应用程序。
我无法理解的一件事是如何在基于node-sqlite3回调的API上使用'yield'语法。
我已经用Google搜索了,我发现的是这个stackoverflow帖子(synchronous sqlite transactions node),这说明这是可能的。
任何人都可以给我一个更具体的例子吗?
提前致谢
答案 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
<强>用法强>
与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);
});
与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);
就像承诺一样
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