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

Jty*_*tan 3 sqlite node.js promise bluebird

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

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

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

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

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

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

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
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

Jty*_*tan 6

我去看node-sqlite3代码,我很确定它this在成功的回调函数中返回的方式,而不是作为一个实际的参数,是问题.这意味着即使尝试使用bluebird的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;
Run Code Online (Sandbox Code Playgroud)

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

在我原来的要求中,我现在做了

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

  • 如果你调用`reject()`,它为什么会命中`.then()`? (2认同)