nodejs sqlite3 db.run作为蓝鸟的承诺

时间:2016-03-20 07:06:56

标签: node.js sqlite promise bluebird

我正在尝试在快递应用中使用sqlite3。 基本上,我得到一个休息请求,根据其他请求,我查询外部REST请求。在外部请求和响应之间的响应从原始REST请求传入的数据,然后我进行更新或插入我的一个sqlite3表。

我遇到的问题是,在db.run(sqlStatement, paramArray, function(err))中,函数(错误)是一个回调,其中err是错误,或nil。除此之外,如果err参数为null,则this引用包含2个属性,其中一个属性告诉我该语句修改的行数。 (https://github.com/mapbox/node-sqlite3/wiki/API#databaserunsql-param--callback供参考)

事情是,我在sqlite3模块上运行bluebird的promisifyAll,然后使用结果

db.runAsync(sqlStatement, paramArray).then(err) {
    console.log(this) //results in a null
}

所以我无法弄清楚是否有任何更新。

我的整段代码看起来有点像这样:

function handleRequest(req, res) {

    //this returns the response as the first object
    request.getAsync('http://www.example.com', reqObj)         
        .then(prepareDbObjects) //prepares an array of objects to update the DB with
        .then(attemptUpdate)
        .then(function(rowsUpdated) {
            res.json(rowsUpdated)
        }
}

function attemptUpdate(updateObjs) {
    var promiseMap = Promise.map(updateObjs, function(singleObj) {
        return updateOrInsertObj(singleObj)
    }
    return promiseMap
}


function updateOrInsertObj(singleObj) {
    return db.runAsync(sqlStatement, singleObj)
        .then(function(err) {
            if(err) {
                //handle error
            } else {
                console.log("this should be an object with 2 properties", this)
                //but instead it is null
            }
        }
}

1 个答案:

答案 0 :(得分:5)

我查看了node-sqlite3代码,我非常确定它在成功的回调函数中返回this的方式,而不是作为一个实际的参数,是问题所在。这意味着即使尝试使用蓝鸟的multiArgs=true参数也没有用,因为没有正确的返回值。

所以我试图将db.run函数包装在我自己的自定义promise方法中,这似乎可以解决问题。

具体来说,我做了:

function runCustomAsync(sql, params) {
    return new Promise(function(resolve, reject) {
        db.run(sql, params, function cb(err) {
            if(err) {
                var responseObj = {
                    'error': err
                }
                reject(responseObj);
            } else {
                var responseObj = {
                    'statement': this
                }
                resolve(responseObj);
            }
        });
    });
}

db.runCustomAsync = runCustomAsync;
module.exports = db;

与正常处理方式略有不同。我现在正在返回一个可能包含this对象的对象,或者它可能包含err对象。

在我的原始请求中,我现在

db.runCustomAsync(sqlStatement, params)
    .then(function(dbResponseObj) {
        if(dbResponseObj.error) {
            //handle error
        } else {
            //do stuff with dbResponseObj.statement
        }
    })