查询方法是异步的,因此您不能期望流程等待它结束。
最基本的方法是在回调中遵循您的流程
console.log("before query1");
connection.query(query1, function (error, results, fields) {
console.log("after query1");
});
但是,如果您想进行子查询,这可能会导致回调噩梦:
connection.query(query1, function (error, results, fields) {
console.log("after query1", {results,fields});
connection.query(query2, function (error2, results2, fields2) {
console.log("after query2", {results2,fields2});
connection.query(query3, function (error3, results3, fields3) {
console.log("after query3, {results3,fields3}");
});
});
});
如果您切换到基于 Promise 的方法,您可以封装对 connection.query 的每个调用以返回一个 Promise,例如:
const mysql = require('mysql-promise'),
connection = mysql.createConnection({...});
connection.connect();
async function queryAsync(sentence) {
return new Promise((resolve, reject) => {
connection.query(sentence, function(error, results, fields) {
if (error) {
reject(error);
}
resolve( results);
});
});
}
然后:
Promise.resolve()
.then(() => {
return queryAsync(sentence1);
})
.then(results1 => {
console.log('after query 1', results1);
return queryAsync(sentence2);
})
.then(results2 => {
console.log('after query 2', results2);
return queryAsync(sentence3);
})
.then(results3 => {
console.log('after query 3', results3);
connection.end();
return;
})
.catch(err => {
console.error(err);
connection.end();
return;
});
或者,使用异步/等待
Promise.resolve().then(async () => {
try {
let results1 = await queryAsync(sentence1);
console.log('after query1', results1);
let results2 = await queryAsync(sentence2);
console.log('after query2', results2);
let results3 = await queryAsync(sentence3);
console.log('after query3', results3);
} catch (err) {
console.error(err);
}
connection.end();
return;
});
已经有一个库可以为您完成上述工作
无论如何,已经有一个包装库 promise-mysql 为您完成承诺包装工作:
# Promise approach
const mysql = require('promise-mysql');
mysql
.createConnection({...})
.then(connection => {
return connection.query(sentence1);
})
.then(results1=>{...})
.catch(err=>{...});
或者
# 异步/等待方法
const mysql = require('promise-mysql');
mysql
.createConnection({...})
.then(async connection => {
try {
let results1 = await connection.query(sentence1);
console.log('after query1', results1);
...
} catch (err) {
console.error(err);
}
return connection.end();
});
试试 RunKit
旁注
顺便说一句:您无需以 Promise.resolve() 开头即可将所有内容包装在异步函数中。我只是觉得
Promise.resolve()
.then(()=> {
…
}).catch(err => {
console.error(err);
});
比
更容易理解
(async () => {
…
})().catch(err => {
console.error(err);
});