我正在尝试在对'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 + '"}');
});
});
答案 0 :(得分:0)
从我的代码中可以看出,你想要做的事情基本上是为具有唯一会话ID的登录用户创建一个新的用户会话,同时确保集合中不存在会话ID。 / p>
因此,对此的解决方案可以是第一个查询,以检查Active_Users集合中是否已存在会话ID,如果没有进行保存调用以使用生成的会话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之类的模块为您完成工作。这将避免不必要的数据库调用并节省性能,并且您的代码将更加整洁。
答案 1 :(得分:0)
虽然我的第一个查询执行,但id_is_valid布尔值永远不会设置为true,因此我的程序会陷入while循环。
这是因为db调用本质上是异步的。如果你运行以下程序,你就会知道它。
'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');
<强>输出强>
没有时间setTimeout被调用61415
没有时间setTimeout被调用61416
没有时间setTimeout Invoked 61417
^ C //我杀了它。
与damitj07一样,我也建议使用像shortId
这样的npms来唯一地生成sessionId。这将帮助您消除数据库调用。
但是,如果您的业务逻辑受到限制,并且您需要以当前的方式来编写它。我想我们可以使用async
&amp; 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();
<强>输出强>
没有时间setTimeout被调用1
这行将被打印
对代码进行更改
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);
}
});
});