[英]Why does the first program work but not the second?
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
database : 'mydb'
})
var values = [ ['Dave', 20],
['Judd', 22],
['Snek', 24],
['Dale', 26]
];
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
let createTodos = `create table if not exists siblings(
id int primary key auto_increment,
name varchar(255)not null,
age tinyint(2) not null default 0
)`;
connection.query(createTodos, function(err, results, fields) {
if (err) {
console.log(err.message);
}
});
var sql = 'insert into siblings (name, age) values ?';
connection.query(sql, [values], function (err, result) {
if (err) throw err;
console.log("Number of records inserted: " + result.affectedRows);
});
});
This works perfectly fine and does what I intended, creates the table with column for name and age if the table does not already exist, then inserts the values in the value array accordingly. 这工作得很好,并达到了我的预期,如果该表尚不存在,则使用名称和年龄列创建该表,然后在值数组中插入相应的值。
This does not work 这行不通
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
database : 'mydb'
})
var values = [ ['Dave', 20],
['Judd', 22],
['Snek', 24],
['Dale', 26]
];
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
let createTodos = `create table if not exists siblings(
id int primary key auto_increment,
name varchar(255)not null,
age tinyint(2) not null default 0
)`;
connection.query(createTodos, function(err, results, fields) {
if (err) {
console.log(err.message);
}
});
});
var sql = 'insert into siblings (name, age) values ?';
connection.query(sql, [values], function (err, result) {
if (err) throw err;
console.log("Number of records inserted: " + result.affectedRows);
});
The difference is that the query to insert the values array is outside of the connect function call. 不同之处在于,用于插入values数组的查询不在connect函数调用之外。 I understand that this must have something to do with the callback functions being passed to connect and them perhaps being async functions, but can someone correct me or elaborate further on this?
我知道这一定与传递给连接的回调函数以及它们可能是异步函数有关,但是有人可以纠正我或对此进行进一步阐述吗? The control flow of node is eluding me.
节点的控制流程使我望而却步。
You need to connect to the database before you can execute queries on the database. 您需要先连接到数据库,然后才能对数据库执行查询。
connection.connect()
is an asynchronous function, which means that when you call it, it begins connecting to the database and returns immediately. connection.connect()
是一个异步函数,这意味着当您调用它时,它将开始连接到数据库并立即返回。 Your code continues on, and when you try and execute a query, the database has not yet connected to the database yet. 您的代码继续进行,并且当您尝试执行查询时,数据库尚未连接到数据库。
This is why it's important to execute your queries in the connection callback. 这就是为什么在连接回调中执行查询很重要的原因。 When your database is connected, the callback allows your code to continue when the database has successfully (Or unsuccessfully) finishes connecting.
连接数据库后,当数据库成功(或未成功)完成连接时,回调函数将允许您的代码继续。
I highly suggest reading into asynchronous programming, and look into promises/await syntax. 我强烈建议阅读异步编程,并研究promise / await语法。 They essentially allow your code to block, by chaining everything neatly instead of involving many many layers of callbacks.
它们本质上是通过将所有内容整齐地链接而不是涉及许多多层的回调来阻止代码。
The promise-mysql
package makes this dirt simple for you: promise-mysql
软件包使您的工作变得简单:
const mysql = require('promise-mysql');
const connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
database : 'mydb'
});
const values = [
['Dave', 20],
['Judd', 22],
['Snek', 24],
['Dale', 26]
];
async main() {
const dbErr = await connection.connect();
if (dbErr) {
return console.error('error: ' + dbErr.message);
}
{
const createTodos = `create table if not exists siblings(
id int primary key auto_increment,
name varchar(255)not null,
age tinyint(2) not null default 0
)`;
const [err, results, fields] = await connection.query(createTodos);
}
{
const insertSiblings = 'insert into siblings (name, age) values ?';
const [err, results, fields] = await connection.query(insertSiblings);
console.log("Number of records inserted: " + result.affectedRows);
}
}
// Call the async function
main();
The issue is that presumably the connect operation takes some time to complete. 问题在于,大概连接操作需要一些时间才能完成。 In the first sample, because the subsequent calls are included in the callback, they happen only after the connection is established to the database.
在第一个示例中,由于后续调用包含在回调中,因此仅在建立与数据库的连接后才发生。
In the second case, because the query is outside the callback to connect, the query is attempted before the connection is established so it fails. 在第二种情况下,因为查询在要连接的回调之外,所以在建立连接之前尝试进行查询,因此连接失败。
Even in the first example, you have the same mistake between the call to create the table and the subsequent call to query it. 即使在第一个示例中,在创建表的调用与随后的查询表之间也存在相同的错误。 But most likely the call to create the table happens so quickly that in most cases it will just work but you are bound to see failures every now and then.
但是创建表的调用很可能发生得如此之快,以至于在大多数情况下它只能工作,但是您一定会时不时地看到失败。
The correct way to write this sequence, using callbacks, is to chain them like so: 使用回调编写此序列的正确方法是像这样将它们链接起来:
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
database : 'mydb'
})
var values = [ ['Dave', 20],
['Judd', 22],
['Snek', 24],
['Dale', 26]
];
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
// this happens only after the connect operation is complete
let createTodos = `create table if not exists siblings(
id int primary key auto_increment,
name varchar(255)not null,
age tinyint(2) not null default 0
)`;
connection.query(createTodos, function(err, results, fields) {
if (err) {
console.log(err.message);
}
// this happens only after the connect & create table are complete
var sql = 'insert into siblings (name, age) values ?';
connection.query(sql, [values], function (err, result) {
if (err) throw err;
// this happens only after connect, create & insert are complete
console.log("Number of records inserted: " + result.affectedRows);
});
});
});
On the second code you put your query outside connection.connect(function(err) { 在第二个代码上,将查询置于connection.connect(function(err){
In the first one it is inside. 在第一个里面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.