我尝试遍历mysql查询结果并进行后续查询,以便构建数据模型。每个对象都需要多个查询,因此我正在链接承诺。
当我嵌套第二组承诺时,问题就出现了。
因此,首先我得到一个需要使用g.getsnapshotids检索的对象列表。然后我遍历这些快照,并使用snapshotid检索完整的快照。
var gData = {};
g.getSnapshotIds(data.gId, data.userId)
.then(function(value) {
gData = value;
for ( var snapshot in value ) {
var snapshotId = value[snapshot].snapshotId;
var snapshot = {};
g.getSnapshotFull(snapshotId)
.then(function(value) {
console.log(value);
return g.getTs(snapshotId);
})
.then(function(value) {
for ( var te in value ) {
var name = value[te].t;
snapshot[name] = value[te].value;
}
console.log(snapshot);
})
.catch(function(err) {
console.log('Error:', err);
});
}
g.close();
})
.catch(function(err) {
console.log('Error:', err);
});
我可以对每个id调用g.getsnapshotfull,但是当我尝试转到下一个查询(g.getts(snapshotid))时,它会给出错误:
Error: Cannot enqueue Query after invoking quit.
我不知道为什么mysql连接在所有查询完成之前就关闭了。for循环中的所有内容不应该在继续之前按顺序执行吗?
如果我注解掉g.close(),我不会得到错误,但过程不会结束。
以下是相关的查询方法:
class gDB {
close() {
return new Promise(function(resolve, reject) {
db.end(function(error) {
if ( error ){
reject(new Error(error));
}
// For some reason it is necessary to reestablish this
db = mysql.createConnection({
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASS,
database: process.env.DBNAME,
ssl: {
ca: fs.readFileSync(__dirname + '/' + process.env.DBCA)
}
});
resolve(true);
});
});
}
getSnapshotIds(gId, uId) {
return new Promise(function(resolve, reject) {
var sql = 'SELECT id AS snapshotId FROM snapshots WHERE gId=' + db.escape(gId) + ' AND uId=' + db.escape(uId) + ' ORDER BY timestamp DESC';
db.query(sql, function (error, results, fields) {
if (error) {
db.destroy();
reject(new Error(error));
} else {
resolve(results);
}
});
});
}
getSnapshotFull(snapshotId) {
return new Promise(function(resolve, reject) {
var sql = 'SELECT s.id AS snapshotId, s.timestamp, s.gId, s.uId, s.clientId FROM snapshots s INNER JOIN controls c ON s.id = c.snapshotId INNER JOIN weathers w ON s.id = w.snapshotId WHERE s.id=' + db.escape(snapshotId);
db.query(sql, function (error, results, fields) {
if (error) {
db.destroy();
reject(new Error(error));
} else {
resolve(results[0]);
}
});
});
}
getTs(snapshotId) {
return new Promise(function(resolve, reject) {
var sql = 'SELECT t.t, st.value FROM snapshots s LEFT JOIN snapshot_t st ON s.id = st.snapshotId INNER JOIN ts t ON st.tId = t.id WHERE s.id=' + db.escape(snapshotId);
db.query(sql, function (error, results, fields) {
if (error) {
db.destroy();
reject(new Error(error));
} else {
resolve(results);
}
});
});
}
1条答案
按热度按时间ymdaylpp1#
问题是循环是同步的,而承诺是异步的。现在的情况是,您正在创建一组承诺,这些承诺正在等待某些事情发生(接收数据的承诺),然后for循环结束(在任何承诺完成之前),然后您调用close。你要做的是类似于下面的事情。
解决这个问题的办法是保留承诺,然后使用
Promise.all(promises)
等待所有的承诺完成。最后一个then块将包含所有承诺的结果,在那里您可以关闭数据库连接。