Неправильный порядок запросов в скрипте Node.js при использовании пакета SQLite3 - PullRequest
1 голос
/ 29 июля 2011

Я играю с пакетом node-sqlite3 и столкнулся со странной ситуацией. Этот простой сценарий имеет простую логику: найдите, если таблица существует, если она очищает ее, если нет - создайте ее.

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('guy.sqlite');    //':memory:'

var tableExists = false;
db.serialize(function() {
    db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='lorem'", function(error, row) {
        tableExists = (row != undefined);
        console.log("xxxxx " +tableExists);
    });

    console.log("yyyyy " +tableExists);

    if (tableExists) {
        console.log("table exists. cleaning existing records");
        db.run("DELETE FROM lorem", function(error) {
            if (error)
                console.log(error);
        });
    }
    else {
        console.log("creating table")
        db.run("CREATE TABLE lorem (info TEXT)", function(error) {
            if (error.message.indexOf("already exists") != -1) {
                console.log(error);
            }
        });
    }
});

db.close();

Но результат, который я получаю:

yyyyy false
creating table
xxxxx true
{ stack: [Getter/Setter],
  arguments: undefined,
  type: undefined,
  message: 'SQLITE_ERROR: table lorem already exists',
  errno: 1,
  code: 'SQLITE_ERROR' }

В соответствии с документацией команды serialize эти запросы должны выполняться последовательно. Тем не менее, очевидно, что оценка tableExists (отмечена 'yyy') происходит до того, как установлено значение (отмечена 'xxx'), что вызывает попытку воссоздания существующей таблицы.
Я могу справиться с этой ошибкой, но мне было интересно, что является причиной этого и как избежать такого поведения в будущем.

Как всегда, спасибо за ваше время.

Guy

Ответы [ 2 ]

1 голос
/ 29 июля 2011

Пример 2 в документации объясняет вашу проблему напрямую.Переменная tableExists будет иметь значение false в первом прогоне, пока функция SELECT ставится в очередь только в цикле событий, и не будет запускаться до тех пор, пока не завершится код в serialize ().Решением было бы разместить код if(tableExists) внутри обратного вызова SELECT.Это побеждает цель использования сериализации, но это так.Запись значений в порядке, потому что они будут поставлены в очередь в том порядке, в котором они были вызваны, но то, что требует ответа через ввод-вывод, потребует обратного вызова и, следовательно, будет выполняться асинхронно.из-за того, что вы вызываете db.close () в конце скрипта, но вне асинхронных обратных вызовов.Несмотря на то, что он находится в конце скрипта, любые асинхронные выпады помещаются в очередь, которая не вызывается до после , когда текущая функция завершена.

1 голос
/ 29 июля 2011

node.js работает в асинхронном режиме, но ваш код представляет собой какую-то странную форму смешанной синхронной и асинхронной формы.

полный код после выбора должен быть в обратном вызове, тогда как ваш реальный код неделай, что хочешь, tableexists не будет иметь тех значений, которые тебе нравятся.

научись любить асинхронную модель node.js;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...