我正在尝试使用MySql进行嵌套查询,将结果放在变量中并通过http发送,但程序在查询完成之前始终运行console.log("test 2:"+rpsData);
。我已经尝试了this,但仍然遇到了同样的问题。
const express = require('express')
const app = express()
const mysql = require('mysql');
const Connection = require('mysql/lib/Connection');
const Promise = require('bluebird');
Promise.promisifyAll([
Connection
]);
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root123',
database : 'mygallery'
});
app.get('/posts', function(request, response) {
var rpsData;
connection.connectAsync()
.then(function() {
connection.query('SELECT * FROM post WHERE approved = 1', function(err, rows, fields) {
if (err) throw err;
rpsData = rows;
for (var i in rows) {
connection.query('SELECT * FROM image WHERE postCode = ?', [rpsData[i].postCode], function(err, rows, fields) {
if (err) throw err;
rpsData[i].image = rows;
console.log("test 1:"+rpsData);
});
}
});
})
.then(function() {
response.send(rpsData);
console.log("test 2:"+rpsData);
})
.catch(function(error) {
console.error('Connection error.', error);
});
});
答案 0 :(得分:1)
这里发生的事情是你没有将所有异步代码绑定到承诺链。一旦我们将其转换为这样做,这应该可行。
首先让我们调用connection.query
来返回一个promise。然后,我们必须返回生成的承诺,将其附加到外部承诺链。
如果你没有回复承诺,它就不会知道它必须等待你的代码完成执行,并且会继续使用外部承诺的下一个.then()语句(来自connection.connectAsync
);
您需要对内部查询应用相同的处理方式。
示例代码:
app.get('/posts', function(request, response) {
connection.connectAsync()
.then(function() {
return new Promise(function(resolve, reject) {
connection.query('SELECT * FROM post WHERE approved = 1', function(err, rows, fields) {
if (err) reject(err);
resolve(rows.reduce(function(accumulator, current) {
return accumulator.then(function(rpsData){
return new Promise(function(resolve, reject){
connection.query('SELECT * FROM image WHERE postCode = ?', [current.postCode], function(err, rows, fields) {
if (err) reject(err);
current.image = rows;
console.log("test 1:"+rpsData);
resolve(rpsData);
});
});
});
}, Promise.resolve(rows)));
});
});
})
.then(function(rpsData) {
response.send(rpsData);
console.log("test 2:"+rpsData);
})
.catch(function(error) {
console.error('Connection error.', error);
});
});
技术对内部承诺进行排队