如何根据另一个查询的结果执行查询? (快递,NodeJS,mysql)
How can I execute a query based on the result of another query? (Express, NodeJS, mysql)
我正在尝试在对我的 'generateSession' 端点进行 API 调用时生成会话 ID。我想确保我没有任何重复的会话 ID,因此我查询数据库以检查生成的 ID 是否匹配。如果不匹配,则 ID 有效,我进行第二次查询以添加具有所述会话 ID 的活动用户。
尽管我执行了第一个查询,但 'id_is_valid' 布尔值从未设置为 true,因此我的程序陷入了 while 循环。
我是 JavaScript 的新手,但根据一些研究,我很确定问题是由于数据库调用的异步性质造成的。但是,我不确定从那里去哪里。有更多 js 知识的人可以给我一些指导吗?
谢谢!
var express = require('express');
var router = express.Router();
var myDB = require('../db-connection');
function generateSession() {
var session_id = '';
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 30; i++) session_id += possible.charAt(Math.floor(Math.random() * possible.length));
return session_id;
}
router.get('/generateSession', function(req, res){
var session_id = '';
var id_is_valid = false;
while (!id_is_valid){
session_id = generateSession();
myDB.query("SELECT * FROM activeUser WHERE session_id = ?", [session_id], function(error, results, field){
if(error) throw error;
else{
if (results.length === 0) is_is_valid = true;
}
});
}
myDB.query("INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)", [session_id], function(error, results, fields){
if (error) res.send('{"success": false}');
else res.send('{"success": true, "session_id": "' + session_id + '"}');
});
});
根据我对您的代码的了解,您要做的基本上是为具有唯一会话 ID 的登录用户创建一个新的用户会话,同时确保该会话 ID 不存在于集合中.
因此,解决此问题的方法是首先查询以检查会话 ID 是否已存在于 Active_Users 集合中,如果不存在,则进行保存调用以使用生成的会话 ID 保存用户。
var express = require('express');
var router = express.Router();
var myDB = require('../db-connection');
function generateSession() {
var session_id = '';
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 30; i++) session_id += possible.charAt(Math.floor(Math.random() * possible.length));
return session_id;
}
router.get('/generateSession', function(req, res) {
var session_id = '';
myDB.query("SELECT * FROM activeUser WHERE session_id = ?", [session_id], function(error, results, field) {
if (error) {
throw error;
} else {
if (results.length === 0) {
//if session id is not present , insert new user
session_id = generateSession();
myDB.query("INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)", [session_id], function(error, results, fields) {
if (error) res.send('{"success": false}');
else res.send('{"success": true, "session_id": "' + session_id + '"}');
});
}
//else do nothing or inser nothing
}
});
});
但理想情况下,如果您每次向 /generate
会话发出请求时都生成一个真正随机的会话 ID,是否真的有必要检查集合中的重复项。
现在,如果生成随机 ID 的逻辑不完美,您始终可以使用像 shortId 这样的模块来为您完成这项工作。这将避免不必要的数据库调用并节省性能,您的代码将更加整洁。
Although my first query executes, the id_is_valid boolean never gets set to true so my program gets stuck in the while loop.
这是因为数据库调用本质上是异步的。如果你运行下面的程序你就知道了。
'use strict';
let id_is_valid = false;
let count = 0;
while (!id_is_valid) {
count++;
console.log(`No of time setTimeout Invoked ${count}`);
setTimeout(function() { // simulating a db call that takes a second for execution
id_is_valid = true;
}, 1000);
}
console.log('This line wont be printed');
输出
No of time setTimeout Invoked 61415
No of time setTimeout Invoked 61416
No of time setTimeout Invoked 61417
^C //I killed it.
与 damitj07 一样,我也建议使用像 shortId
这样的 npms 来唯一生成 sessionId。这将帮助您消除数据库调用。
但是,如果您的业务逻辑受到限制并且您需要以您编写的当前方式使用它。我想我们可以使用 async
& await
'use strict';
let isFound = false;
let count = 0;
function doDbQuery() {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(true);
}, 2000);
});
}
async function run() {
while (!isFound) {
count++;
console.log(`No of time setTimeout Invoked ${count}`);
isFound = await doDbQuery();
}
console.log('This line WILL BE printed');
}
run();
输出
No of time setTimeout Invoked 1
This line WILL BE printed
对您的代码进行这些更改,
router.get('/generateSession', async function (req, res) {
var session_id = '';
var id_is_valid = false;
while (!id_is_valid) {
session_id = generateSession();
id_is_valid = await checkSessionIdInDb(session_id);
}
myDB.query('INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)', [session_id], function (error, results, fields) {
if (error) {
res.send('{"success": false}');
} else {
res.send('{"success": true, "session_id": "' + session_id + '"}');
}
});
});
function checkSessionIdInDb() {
return new Promise((resolve, reject) => {
myDB.query('SELECT * FROM activeUser WHERE session_id = ?', [session_id], function (error, results, field) {
if (error) {
return reject(error);
} else {
if (results.length === 0) {
resolve(true);
}
resolve(false);
}
});
});
我正在尝试在对我的 'generateSession' 端点进行 API 调用时生成会话 ID。我想确保我没有任何重复的会话 ID,因此我查询数据库以检查生成的 ID 是否匹配。如果不匹配,则 ID 有效,我进行第二次查询以添加具有所述会话 ID 的活动用户。
尽管我执行了第一个查询,但 'id_is_valid' 布尔值从未设置为 true,因此我的程序陷入了 while 循环。
我是 JavaScript 的新手,但根据一些研究,我很确定问题是由于数据库调用的异步性质造成的。但是,我不确定从那里去哪里。有更多 js 知识的人可以给我一些指导吗?
谢谢!
var express = require('express');
var router = express.Router();
var myDB = require('../db-connection');
function generateSession() {
var session_id = '';
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 30; i++) session_id += possible.charAt(Math.floor(Math.random() * possible.length));
return session_id;
}
router.get('/generateSession', function(req, res){
var session_id = '';
var id_is_valid = false;
while (!id_is_valid){
session_id = generateSession();
myDB.query("SELECT * FROM activeUser WHERE session_id = ?", [session_id], function(error, results, field){
if(error) throw error;
else{
if (results.length === 0) is_is_valid = true;
}
});
}
myDB.query("INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)", [session_id], function(error, results, fields){
if (error) res.send('{"success": false}');
else res.send('{"success": true, "session_id": "' + session_id + '"}');
});
});
根据我对您的代码的了解,您要做的基本上是为具有唯一会话 ID 的登录用户创建一个新的用户会话,同时确保该会话 ID 不存在于集合中.
因此,解决此问题的方法是首先查询以检查会话 ID 是否已存在于 Active_Users 集合中,如果不存在,则进行保存调用以使用生成的会话 ID 保存用户。
var express = require('express');
var router = express.Router();
var myDB = require('../db-connection');
function generateSession() {
var session_id = '';
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 30; i++) session_id += possible.charAt(Math.floor(Math.random() * possible.length));
return session_id;
}
router.get('/generateSession', function(req, res) {
var session_id = '';
myDB.query("SELECT * FROM activeUser WHERE session_id = ?", [session_id], function(error, results, field) {
if (error) {
throw error;
} else {
if (results.length === 0) {
//if session id is not present , insert new user
session_id = generateSession();
myDB.query("INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)", [session_id], function(error, results, fields) {
if (error) res.send('{"success": false}');
else res.send('{"success": true, "session_id": "' + session_id + '"}');
});
}
//else do nothing or inser nothing
}
});
});
但理想情况下,如果您每次向 /generate
会话发出请求时都生成一个真正随机的会话 ID,是否真的有必要检查集合中的重复项。
现在,如果生成随机 ID 的逻辑不完美,您始终可以使用像 shortId 这样的模块来为您完成这项工作。这将避免不必要的数据库调用并节省性能,您的代码将更加整洁。
Although my first query executes, the id_is_valid boolean never gets set to true so my program gets stuck in the while loop.
这是因为数据库调用本质上是异步的。如果你运行下面的程序你就知道了。
'use strict';
let id_is_valid = false;
let count = 0;
while (!id_is_valid) {
count++;
console.log(`No of time setTimeout Invoked ${count}`);
setTimeout(function() { // simulating a db call that takes a second for execution
id_is_valid = true;
}, 1000);
}
console.log('This line wont be printed');
输出
No of time setTimeout Invoked 61415
No of time setTimeout Invoked 61416
No of time setTimeout Invoked 61417
^C //I killed it.
与 damitj07 一样,我也建议使用像 shortId
这样的 npms 来唯一生成 sessionId。这将帮助您消除数据库调用。
但是,如果您的业务逻辑受到限制并且您需要以您编写的当前方式使用它。我想我们可以使用 async
& await
'use strict';
let isFound = false;
let count = 0;
function doDbQuery() {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(true);
}, 2000);
});
}
async function run() {
while (!isFound) {
count++;
console.log(`No of time setTimeout Invoked ${count}`);
isFound = await doDbQuery();
}
console.log('This line WILL BE printed');
}
run();
输出
No of time setTimeout Invoked 1
This line WILL BE printed
对您的代码进行这些更改,
router.get('/generateSession', async function (req, res) {
var session_id = '';
var id_is_valid = false;
while (!id_is_valid) {
session_id = generateSession();
id_is_valid = await checkSessionIdInDb(session_id);
}
myDB.query('INSERT INTO activeUser (is_registered, session_id) VALUES (0, ?)', [session_id], function (error, results, fields) {
if (error) {
res.send('{"success": false}');
} else {
res.send('{"success": true, "session_id": "' + session_id + '"}');
}
});
});
function checkSessionIdInDb() {
return new Promise((resolve, reject) => {
myDB.query('SELECT * FROM activeUser WHERE session_id = ?', [session_id], function (error, results, field) {
if (error) {
return reject(error);
} else {
if (results.length === 0) {
resolve(true);
}
resolve(false);
}
});
});