Node.js和sqlite3 npm模块:分别获取数据库#中的所有行

我使用node.js版本0.10.24和名为sqlite3版本2.1.19的npm模块。 我使用terminal窗口在OS X 10.9.1盒子上testing我的脚本。 以下脚本:

var sqlite3 = require('sqlite3').verbose() var async = require('async') var myList = [] var db = new sqlite3.Database('./test0.db') async.series([ // Create a table and populate it function (callback) { db.run("CREATE TABLE lorem (listnumb bigint, info TEXT)", function (err) { if (err) return callback(err) console.log('Table created. ') callback() }); }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) for (var i = 0; i < 10; i++) { stmt.run(i, "Ipsum " + i) } stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { db.each("SELECT listnumb as numb, info FROM lorem;", function (err, row) { if (err) return callback(err) console.log(' numb = ' + row.numb + ' info field = ' + row.info) }, function (err, cntx) { if (err) return callback(err) console.log('Number of retrieved rows is ' + cntx) callback() } ) } ], // This function gets called after the tasks above have completed function(err) { if (err) return new Error(err) console.log("\n\nLength of array after the function go runs " + myList.length) db.close() }) 

似乎工作,直到db.each方法。 该方法实际上不会返回表lorem中的所有行。

 $ node pacheco3.js Table created. Table populated. numb = 0 info field = Ipsum 0 numb = 1 info field = Ipsum 1 numb = 2 info field = Ipsum 2 numb = 3 info field = Ipsum 3 numb = 4 info field = Ipsum 4 numb = 5 info field = Ipsum 5 Number of retrieved rows is 6 

当我通过运行SQLite shell来查询数据库表时,我得到了这些结果:

  $ sqlite3 test0.db SQLite version 3.8.2 2013-12-06 14:53:30 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select listnumb as numb, info from lorem; 0|Ipsum 0 1|Ipsum 1 2|Ipsum 2 3|Ipsum 3 4|Ipsum 4 5|Ipsum 5 6|Ipsum 6 7|Ipsum 7 8|Ipsum 8 9|Ipsum 9 sqlite> .exit 

我在db.each的代码中做了一个业余的错误吗? 我对node.js和asynchronous(非阻塞)代码的Node风格相当陌生。

这是因为stmt.run()本身是asynchronous的,所以同步函数

 function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) for (var i = 0; i < 10; i++) { stmt.run(i, "Ipsum " + i) } stmt.finalize(); console.log('Table populated. ') callback() }) }, 

创build10个asynchronousstmt.run()任务来运行,这10个任务中的任意数量可以在插入函数完成之前运行,所以当select函数运行的时候,仍然有stmt.run任务堆积在它后面(之后运行,这就是为什么当你查询数据库,他们都存在)。

如果代码更改为

 var sqlite3 = require('sqlite3').verbose() var async = require('async') var myList = [] var db = new sqlite3.Database('./test0.db') async.series([ // Create a table and populate it function (callback) { db.run("CREATE TABLE lorem (listnumb bigint, info TEXT)", function (err) { if (err) return callback(err) console.log('Table created. ') callback() }); }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(0, "Ipsum " + 0) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(1, "Ipsum " + 1) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(2, "Ipsum " + 2) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(3, "Ipsum " + 3) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(4, "Ipsum " + 4) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(5, "Ipsum " + 5) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(6, "Ipsum " + 6) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(7, "Ipsum " + 7) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(8, "Ipsum " + 8) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { stmt = db.prepare("INSERT INTO lorem VALUES (?, ?);", function (err) { if (err) return callback(err) stmt.run(9, "Ipsum " + 9) stmt.finalize(); console.log('Table populated. ') callback() }) }, function (callback) { db.each("SELECT listnumb as numb, info FROM lorem;", function (err, row) { if (err) return callback(err) console.log(' numb = ' + row.numb + ' info field = ' + row.info) }, function (err, cntx) { if (err) return callback(err) console.log('Number of retrieved rows is ' + cntx) callback() } ) } ], // This function gets called after the tasks above have completed function(err) { if (err) return new Error(err) console.log("\n\nLength of array after the function go runs " + myList.length) db.close() }) 

那么输出是

 Table created. Table populated. Table populated. Table populated. Table populated. Table populated. Table populated. Table populated. Table populated. Table populated. Table populated. numb = 0 info field = Ipsum 0 numb = 1 info field = Ipsum 1 numb = 2 info field = Ipsum 2 numb = 3 info field = Ipsum 3 numb = 4 info field = Ipsum 4 numb = 5 info field = Ipsum 5 numb = 6 info field = Ipsum 6 numb = 7 info field = Ipsum 7 numb = 8 info field = Ipsum 8 numb = 9 info field = Ipsum 9 Number of retrieved rows is 10 Length of array after the function go runs 0 

数组长度为0,因为不使用myList。