javascript - 在 Node.js 中执行顺序操作
问题描述
我用 node.js 为自己构建了一个辅助函数来准备一个数据库,我目前经常在其中对表结构进行更改。因此,我在全局对象“表”中定义了我的数据库结构,并通过 sql-queries 使用 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 函数返回一个承诺,您可以等待这些函数的结果。
出于演示的目的,我已经模拟了 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)
}
推荐阅读
- python - 如何在手风琴Python中抓取隐藏的文本
- javascript - 在同一页面上调用一个 javascript 弹出窗口,该页面应该在输入文本中具有动态值
- node.js - Node.js中的SFTP上传空文件
- unity3d - unity build error 找不到:AndroidTargetDevice
- azure - “分区低于目标副本或实例计数”,Service Fabric 本地群集上有状态服务
- php - DocuSign PHP SDK - 为什么我调用 createEnvelope() 时会发送两封电子邮件?
- flutter - Flutter ScrollController 在 NestedScrollView 中的位置
- python - 如何提高文本解析功能的性能?
- python - 我如何登录到这个特定的网站/如何使用 cookie 文件登录
- r - 如何使用 tidyverse 将相应的文件名添加为新列