【问题标题】:nodejs sqlite3 db.run as a bluebird promisenodejs sqlite3 db.run 作为蓝鸟承诺
【发布时间】:2016-07-06 18:50:48
【问题描述】:

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

我遇到的问题是,在db.run(sqlStatement, paramArray, function(err)) 中,函数(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
            }
        }
}

【问题讨论】:

    标签: node.js sqlite promise bluebird


    【解决方案1】:

    我查看了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;
    

    这与通常的处理方式略有不同。我现在返回的对象可能包含this 对象,也可能包含err 对象。

    在我最初的要求中,我现在这样做

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

    【讨论】:

    • 如果你打电话给reject(),为什么会打到.then()
    • 如果你使用 .then() 那么你可以使用 .catch(error) 从 promise 中捕获错误 else 在异步函数中你可以尝试 { await function()} catch(e) {/ / 做某事}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 2014-11-08
    • 1970-01-01
    • 2014-02-13
    • 2014-11-06
    相关资源
    最近更新 更多