通知调用者node.js中回调的错误与sqlite3调用的错误

通知调用者node.js中回调的错误与sqlite3调用的错误,node.js,sqlite,callback,Node.js,Sqlite,Callback,在node.js+sqlite3中: 从回调中通知调用方错误并让调用方重试的好方法是什么?当我们得到一个数据库锁定错误-希望尝试再次运行查询 TestController.prototype.addDevices = function (number_of_devices, callback_after_all_devices_have_been_added) { var controller = this; var db = controller.connectToDb();

在node.js+sqlite3中:

从回调中通知调用方错误并让调用方重试的好方法是什么?当我们得到一个数据库锁定错误-希望尝试再次运行查询

TestController.prototype.addDevices = function (number_of_devices, callback_after_all_devices_have_been_added) {
    var controller = this;
    var db = controller.connectToDb();

    for(i = 0; i < number_of_devices; i++) {
        db.each("SELECT api_key as ak FROM user_table ORDER BY RANDOM() LIMIT 1", function(err, row) {
            //sometimes we get a SQLITE: database locked error
            if (err !== null) {
                console.log("Error found");
                //i-- this will not work - but how do we do it then?
                return;
            }
            console.log("Error: " + err);
            //code to process if we get an entry from the user_table ..
        });
    }
}

我就是这样设法解决这个问题的——添加了一个重试计数器,并将问题代码移动到它自己的函数中,作为回调传入尾声。这是可行的,但这是一个好方法吗? 除了使用承诺或异步模块之外

TestController.prototype.addDevices = function (number_of_devices, callback_after_all_devices_have_been_added) {
    var number_of_users = 0;
    var controller = this;
    controller.pending_db_writes_for_device = number_of_devices;

    for(i = 0; i < number_of_devices; i++) {
        var api_key = controller.getRandomAPIKeyFromDB(10,function(access_key) {
            var mac_address = controller.generateRandomMAC();
            var friendly_name = Faker.random.array_element(["Washing Machine","Television","Dishwasher","Set top box"]);
            var description = Faker.Lorem.sentence(5);
            controller.registerDeviceWithAPI(mac_address, friendly_name, description, access_key, callback_after_all_devices_have_been_added);
        });
    }
}

TestController.prototype.getRandomAPIKeyFromDB = function (retry_counter, callback) {
  var controller = this;
  var db = controller.connectToDb();
  console.log("Retry counter: "+ retry_counter);
  db.each("SELECT api_key as ak FROM user_table ORDER BY RANDOM() LIMIT 1", function(err, row) {
            if (err !== null) {
                console.log("Error: " + err + "retry count: "+ retry_counter);
                console.log("Error found");
                if(retry_counter === 0) {
                    console.log("Bailing out after retry limit reached");
                    return;
                }
                controller.getRandomAPIKeyFromDB(--retry_counter,callback);
            }
            else {
                console.log("Successfully got api key: " + row.ak);
                callback(row.ak);
            }
        }
    );
}

由于for循环,将出现数据库锁定错误。for循环不会等待db.each完成。它只是继续到下一个迭代,调用db.each.but后,我想对指定数量的设备(即for循环中的计数器)执行db.each-我有时会锁定数据库,通常在第一次尝试时,10次中只有一次锁定数据库。您可以查看async.eachSeries async模块,以确保db.each在进入下一次尝试之前完成。由于您的问题是关于如何重试,您可以查看节点重试模块,该模块允许您在失败之前重试x次。谢谢!将研究你提到的模块-如果我可以使用这些模块解决问题,将发布。有没有任何通用方法可以让回调函数通知调用者错误?我们遵循的惯例是在调用回调函数时传递两个参数。callbackerr,result;如果没有错误,只需传递error=null。callbackerr;如果存在错误,则只需传递错误。callbacknull,结果;添加所有设备后,您的回调将被调用十次?这可能是意想不到的行为。是的。。。谢谢我正在检查此计数器。仅当此设备的.pending_db_writes_为零时,才在controller.registerDeviceWithAPI中添加所有设备后调用回调。但我现在有了不同的意外行为。如果您能看一下,并告诉我可以修复哪些问题,我将不胜感激。我得到了意想不到的行为:有时在auth表中创建了重复的条目。错误检查sqlite3错误很困难,或者我做错了什么。