如何使用q(承诺)节点sqlite3

时间:2014-03-11 13:01:38

标签: javascript sqlite promise

我正在尝试使用sqlite3的promise。这是我的源代码的一部分:

this.deleteTag = function(tag, project){
    var db = this.db;
    if (project){
        return q.nfcall(db.run, "DELETE FROM tag2project WHERE tag = ? AND project = ?",
            [tag.id, project.id]);
    }else{
        return q.all([
            q.nfcall(db.run, "DELETE FROM tag2project WHERE tag = ?", [tag.id]),
            q.nfcall(db.run, "DELETE FROM tags WHERE id = ?", [tag.id])
        ]);
    }
};

但是那些承诺只会输入.fail,其中错误是:

[TypeError: Database object expected]

搜索此错误只会让我看到sqlite本身的源代码https://github.com/joyent/smartos-live/blob/master/src/node-sqlite3/src/statement.cc#L91

使用简单回调的旧版本正在运行,因此this.db或sql查询中没有错误。

2 个答案:

答案 0 :(得分:5)

我认为db.run不是函数而是方法。来自Q doc:

  

如果您正在使用方法而不是简单的函数,则可以   容易遇到将方法传递给另一个方法的常见问题   类似函数Q.nfcall-从其所有者“取消绑定”该方法。避免   这个,你可以使用Function.prototype.bind或者一些不错的   我们提供的快捷方法:

return Q.ninvoke(redisClient, "get", "user:1:id");
return Q.npost(redisClient, "get", ["user:1:id"]);

但我总是使用Q.denodeify或Q.nbind。它更干净。

  

您还可以使用Q.denodeify或Q.nbind:

创建可重复使用的包装器
var readFile = Q.denodeify(FS.readFile);
return readFile("foo.txt", "utf-8");

var redisClientGet = Q.nbind(redisClient.get, redisClient);
return redisClientGet("user:1:id");

答案 1 :(得分:0)

您可以绑定功能化时创建的对象。

示例

const { promisify } = require('util');
const db = new lib_sqlite3.Database(_dirname + '/your-db-path');

const runAsync = promisify(db.run.bind(db));