node.js中的异步编程排序问题

时间:2018-07-18 11:09:04

标签: node.js asynchronous sqlite callback

我选择了一个项目,在该项目中,首次启动node.js程序时,将不存在任何数据库。程序应该创建数据库表(如果尚不存在)。

但是,在下面的示例程序中,如果由于select语句失败而在第一次运行时不存在数据库,则不会插入数据。

下面的代码输出为:

$ node dbtest.js
finished initialise_database
program ended.
select err:  { Error: SQLITE_ERROR: no such table: mytable errno: 1, code: 'SQLITE_ERROR' }
successfully created mytable table
database closed.

从日志记录中可以看到,代码假定同步执行。

我假设发生的事情是node.js运行时系统使用不同的线程来调度数据库函数以并行运行。

在继续操作之前,我需要CREATE TABLE命令才能完成。我将如何实现?

在node.js中是否有某种标准的方法来实现这一目标?

以下代码:

// npm install sqlite3 - to install sqlite3


const sqlite3 = require('sqlite3').verbose();

let db = initialise_database();

check_and_update(db); //Calling this function upon starting the server.

close_database(db);

console.log('program ended.');


function initialise_database() {
    //Establishing a database connection.
    let db = new sqlite3.Database('database1.db', (err)=>{
        if(err) {
            return console.error(err.message);
        }
    });

//    // new db always succeeds even if no file exists - if empty file have to generate table structure
    db.run("CREATE TABLE IF NOT exists 'mytable' ('num1' INTEGER, 'num2' INTEGER, 'text1' TEXT);", function(err) {
        if (err) {
        console.log("Create table error: ", err);
    }
    console.log("successfully created mytable table");
    });

    console.log("finished initialise_database");
    return db;
}


function check_and_update(db) {
    db.all("SELECT * FROM mytable", function(err, data){
        if(err) {
            console.log("select err: ", err);
        } else {
            db.run('INSERT INTO mytable (num1, num2, text1) VALUES (?, ?, ?)', [1, 2, 'hi guys!!!'], function(err){
            if(err)
                console.log("insert err: ", err);

            });
        }
    });
}


function close_database(db) {
    db.close((err) => {
        if (err) {
            return console.error(err.message);
        }
        console.log('database closed.');    
    });
}

1 个答案:

答案 0 :(得分:0)

数据库请求是异步的,您必须以异步方式处理它们。

可以是:

  • Callback
  • Promise
  • Async/await

否则,您将尝试对未初始化的数据库执行请求。

以下是使用Promise的示例。

const sqlite3 = require('sqlite3').verbose();

let dbPtr = false;

initialise_database()
  .then((db) => {
    dbPtr = db;

    return check_and_update(dbPtr);
  })
  .then(() => {
    close_database(dbPr);
     
    // All is done

    console.log('program ended.');
  })
  .catch((err) => {
    // Deal with the error
  });

function initialise_database() {
  return new Promise((resolve, reject) => {
    //Establishing a database connection.
    const db = new sqlite3.Database('database1.db', (err) => {
      if (err) {
        console.error(err.message);

        return reject(err);
      }

      db.run('...', function(err) {
        if (err) {
          console.log("Create table error: ", err);

          return reject(err);
        }

        console.log("successfully created mytable table");

        return resolve(db);
      });
    });
  });
}

function check_and_update(db) {
  return new Promise((resolve, reject) => {
    db.all('...', function(err, data) {
      if (err) {
        console.log("select err: ", err);

        return reject(err);
      }

      db.run('...', [1, 2, 'hi guys!!!'], function(err) {
        if (err) {
          console.log("insert err: ", err);

          return reject(err);
        }

        return resolve();
      });
    });
  });
}


function close_database(db) {
  db.close();
}


@EDIT

看着documentation,看来db.close()没有在参数中进行回调。我已经修改了代码段。

enter image description here