javascript - 在 Node.js 中执行顺序操作

标签 javascript sql node.js asynchronous async-await

我用 node.js 为自己构建了一个辅助函数来准备数据库,目前我经常在其中更改表结构。因此,我在全局对象“表”中定义了数据库结构,并通过 sql 查询使用 mssql 库构建了表。总而言之,一切顺利。但我现在在 init 函数的末尾添加了一个 process.exit(1) ,这表明解释器无需等待 sql 执行即可完成操作。如何修改代码,使解释器能够正确执行所有步骤并随后退出程序?

const tables = {

    table_name_1: {
        "key1": "nvarchar(25)",
        "key2": "int",
        "..": "bit",
    },
    table_name_2: {
        "key1": "int",
        "key2": "nvarchar(50)",
        "..": "int",
    },
    table_name_3: {
        "key1": "int",
        "key2": "int",
        "..": "int",
    }
    
}

init_environment();

function init_environment() {

    console.log("Init started...");

    delete_table(Object.keys(tables));
    create_table(Object.keys(tables));

    console.log("Init finished");
    process.exit(1);
}

function delete_table(tables_to_delete) {

    sql.connect(SQL_CONFIG, function () {

        for (var i = 0; i < tables_to_delete.length; i++) {

            var request = new sql.Request();
            var query = "DROP TABLE " + tables_to_delete[i];

            request.query(query, function (err, recordset) {
                if (err) {
                    console.log(err);
                } 
            });

        }

    })

}

function create_table(tables_to_create) {

    sql.connect(SQL_CONFIG, function () {

        for (var i = 0; i < tables_to_create.length; i++) {

            var request = new sql.Request();

            var query = "CREATE TABLE " + tables_to_create[i] + " (id INT IDENTITY(1,1) PRIMARY KEY, ";

            for (var key in tables[tables_to_create[i]]) {
                query += key + " " + tables[tables_to_create[i]][key] + ", ";
            }

            query += ")";

            request.query(query, function (err, recordset) {
                if (err) {
                    console.log(err);
                }
            });

        }

    })

}

最佳答案

您应该能够使用async/await来实现此目的。如果您的delete_table/create_table函数返回一个promise,您可以等待这些函数的结果。

出于演示目的,我模拟了 sql 函数(以及 process.exit())。您可以看到查询将按顺序运行,然后进程将退出。

事实证明,如果没有传递回调,sql.connect() 和 sql.close() 将返回 Promises。这使得代码编写起来更加简单。

Node.js 代码

const tables = {

    table_name_1: {
        "key1": "nvarchar(25)",
        "key2": "int"
    },
    table_name_2: {
        "key1": "int",
        "key2": "nvarchar(50)",
    },
    table_name_3: {
        "key1": "int",
        "key2": "int"
    }
    
}

init_environment();

async function init_environment() {

    console.log("Init started...");

    await delete_table(Object.keys(tables));
    await create_table(Object.keys(tables));

    console.log("Init finished");
    process.exit(1);
}

async function delete_table(tables_to_delete) {
    await sql.connect(SQL_CONFIG);
    for (var i = 0; i < tables_to_delete.length; i++) {
        var query = "DROP TABLE IF EXISTS " + tables_to_delete[i];
        await runQuery(query);
    }
    await sql.close();
}

async function create_table(tables_to_create) {
    await sql.connect(SQL_CONFIG);
    
    for (var i = 0; i < tables_to_create.length; i++) {

        var query = "CREATE TABLE " + tables_to_create[i] + " (id INT IDENTITY(1,1) PRIMARY KEY, ";

        for (var key in tables[tables_to_create[i]]) {
            query += key + " " + tables[tables_to_create[i]][key] + ", ";
        }

        query += ")";
        
        await runQuery(query);
    }
    await sql.close();
}

function runQuery(query) {
     console.log("runQuery: Running query: " + query);
     var request = new sql.Request();
     return request.query(query);
}

演示片段

/* Mock code */
const SQL_CONFIG = "Some config"
const sql = { 
   connect(config) {
       return new Promise(resolve => setTimeout(resolve, 1000));
   },
   close() { 
       return new Promise(resolve => setTimeout(resolve, 1000));
   }
}

class Request {
    query(query) {
        return new Promise(resolve => setTimeout(resolve, 500, null, {}));
    }
}

sql.Request = Request;

process = { 
    exit() {
        console.log("Exiting process...");
    }
}

/* End Mock code */

const tables = {

    table_name_1: {
        "key1": "nvarchar(25)",
        "key2": "int",
        "..": "bit",
    },
    table_name_2: {
        "key1": "int",
        "key2": "nvarchar(50)",
        "..": "int",
    },
    table_name_3: {
        "key1": "int",
        "key2": "int",
        "..": "int",
    }
    
}

init_environment();

async function init_environment() {

    console.log("Init started...");

    await delete_table(Object.keys(tables));
    await create_table(Object.keys(tables));

    console.log("Init finished");
    process.exit(1);
}

async function delete_table(tables_to_delete) {
    await sql.connect(SQL_CONFIG);
    for (var i = 0; i < tables_to_delete.length; i++) {
        var query = "DROP TABLE " + tables_to_delete[i];
        await runQuery(query);
    }
    await sql.close();
}

async function create_table(tables_to_create) {
    await sql.connect(SQL_CONFIG);
    
    for (var i = 0; i < tables_to_create.length; i++) {
        let lastQuery = i === tables_to_create.length -1;

        var query = "CREATE TABLE " + tables_to_create[i] + " (id INT IDENTITY(1,1) PRIMARY KEY, ";

        for (var key in tables[tables_to_create[i]]) {
            query += key + " " + tables[tables_to_create[i]][key] + ", ";
        }

        query += ")";
        
        await runQuery(query);
    }
    await sql.close();
}

function runQuery(query) {
     console.log("runQuery: Running query: " + query)
     var request = new sql.Request();
     return request.query(query)
}

关于javascript - 在 Node.js 中执行顺序操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66261442/

相关文章:

javascript - 在特定段落 <p> 元素上动态更改字体大小?

javascript - 无法使用图像叠加添加 bing 主题

javascript - 如何为每个div添加一个JSON值?

mysql - SQL 不适用于同一表中一列到另一列的简单 SET

node.js - 将电子邮件模板与 node.js + sendgrid 结合使用

javascript - 重试nodejs http.request(发布、放置、删除)

git - 在 Heroku 应用程序中包含第二个独立存储库?

javascript - 如何从动态生成的 <option> <select> Express ejs 中获取值

sql - 分别提取数字和特殊字符

SQL- 当前季度的数据必须被截断并重新加载,但上一季度的数据应该保持不变