AngularJS & Socket.IO - Return 从服务(在此处发出)到控制器的值未定义 ||承诺,异步
AngularJS & Socket.IO - Return value from Service (emit here) to Controller is undefined || promises, asynchronicity
我的代码无法正常工作。
我正在使用 AngularJS 开发一个应用程序,包括通过 socket.io 连接到后端服务器。我正在处理旨在将用户数据发送到服务器的登录。如果发送的数据(电子邮件和密码)正确,则服务器将以 "valid" 和用户数据(姓名、出生日期等)进行响应。元素是:
- BackendService(执行 emit 到服务器的工厂)
- AppController(调用BackendService登录功能的Controller)
- Node.js 服务器(计算发送的数据是否有效以便用户可以登录)
意图是工厂中的登录函数 returns 一个 "login code" 告诉控制器登录是否正确。不幸的是 函数 returns "undefined"。在研究过程中,我发现这可能是因为异步和承诺。但是,我无法将给定的信息应用到我的问题中,因为大多数是关于 $http 的。此外 - 如果我的代码结构需要改进,请告诉我!
这是我的代码:
Node.js服务器
socket.on('logincust', function (p1, fn) {
connection.query("SELECT Salt FROM Customer WHERE Email = ?", [p1.Email], function (err, data, fields)
{
if (err) {
throw err;
}
if (data.length > 0) {
var hash = crypto.createHash('sha256').update(p1.Password + data[0].Salt).digest('base64');
connection.query("SELECT LName,FName,Email,Telephone,Address,DateOfBirth FROM Customer WHERE Password = ?", [hash], function (err, data2, fields) {
if (err) {
throw err;
}
if (data2.length > 0) {
fn('valid', data2[0]);
}
else {
fn('invalidpassword', 'nodata')
}
})
}
else {
fn('invalidemail','nodata')
}
})
})
后端服务(工厂)
"use strict";
mobileClientApp.factory('BackendService', function() {
var mySocket = io.connect('http://thisLinkIsPrivate:8888/ns');
return {
login: function (pUserData) {
if (mySocket.connected) {
mySocket.emit('logincust', pUserData, function (resp, data) {
if (resp == "valid") {
var parsedData = JSON.stringify(data);
console.log(parsedData);
user.lName = parsedData.LName; // Fill userData
user.fName = parsedData.FName;
user.email = parsedData.Email;
user.phoneCallcenter = parsedData.Telephone;
console.info("Login successful.");
return 0;
}
else {
if (resp == "invalidpassword") {
return 1;
}
else if (resp == "invalidemail") {
return 2;
}
}
});
}
else { // Socket is not connected
console.warn("Socket not connected.);
user.fName = "Peter";
user.lName = "Offline";
return -1;
}
};
Angular控制器
$scope.doLogin = function() {
var user = {'Email': this.loginData.username, 'Password': this.loginData.password};
var isLoggedIn = BackendService.login(user); // 0 - logged in, 1 - invalid password, 2 - invalid email, -1 - socket not connected
console.log("BackendService.login(user): " + BackendService.login(user)); // is undefined!
console.log("isLoggedIn: " + isLoggedIn); // undefined!
if (isLoggedIn == 0 || isLoggedIn == -1) {
$location.path('/app/landing');
}
else {
$scope.errorMessage = "Invalid login data!";
}
};
是的,问题似乎是异步的。如果你想访问登录方法的结果,你应该向它传递一个回调。因为在您调用它之后,下一次执行将是您的控制台日志,并且会在您的 SQL 查询 returns 结果之前发生。
我的代码无法正常工作。
我正在使用 AngularJS 开发一个应用程序,包括通过 socket.io 连接到后端服务器。我正在处理旨在将用户数据发送到服务器的登录。如果发送的数据(电子邮件和密码)正确,则服务器将以 "valid" 和用户数据(姓名、出生日期等)进行响应。元素是:
- BackendService(执行 emit 到服务器的工厂)
- AppController(调用BackendService登录功能的Controller)
- Node.js 服务器(计算发送的数据是否有效以便用户可以登录)
意图是工厂中的登录函数 returns 一个 "login code" 告诉控制器登录是否正确。不幸的是 函数 returns "undefined"。在研究过程中,我发现这可能是因为异步和承诺。但是,我无法将给定的信息应用到我的问题中,因为大多数是关于 $http 的。此外 - 如果我的代码结构需要改进,请告诉我!
这是我的代码:
Node.js服务器
socket.on('logincust', function (p1, fn) {
connection.query("SELECT Salt FROM Customer WHERE Email = ?", [p1.Email], function (err, data, fields)
{
if (err) {
throw err;
}
if (data.length > 0) {
var hash = crypto.createHash('sha256').update(p1.Password + data[0].Salt).digest('base64');
connection.query("SELECT LName,FName,Email,Telephone,Address,DateOfBirth FROM Customer WHERE Password = ?", [hash], function (err, data2, fields) {
if (err) {
throw err;
}
if (data2.length > 0) {
fn('valid', data2[0]);
}
else {
fn('invalidpassword', 'nodata')
}
})
}
else {
fn('invalidemail','nodata')
}
})
})
后端服务(工厂)
"use strict";
mobileClientApp.factory('BackendService', function() {
var mySocket = io.connect('http://thisLinkIsPrivate:8888/ns');
return {
login: function (pUserData) {
if (mySocket.connected) {
mySocket.emit('logincust', pUserData, function (resp, data) {
if (resp == "valid") {
var parsedData = JSON.stringify(data);
console.log(parsedData);
user.lName = parsedData.LName; // Fill userData
user.fName = parsedData.FName;
user.email = parsedData.Email;
user.phoneCallcenter = parsedData.Telephone;
console.info("Login successful.");
return 0;
}
else {
if (resp == "invalidpassword") {
return 1;
}
else if (resp == "invalidemail") {
return 2;
}
}
});
}
else { // Socket is not connected
console.warn("Socket not connected.);
user.fName = "Peter";
user.lName = "Offline";
return -1;
}
};
Angular控制器
$scope.doLogin = function() {
var user = {'Email': this.loginData.username, 'Password': this.loginData.password};
var isLoggedIn = BackendService.login(user); // 0 - logged in, 1 - invalid password, 2 - invalid email, -1 - socket not connected
console.log("BackendService.login(user): " + BackendService.login(user)); // is undefined!
console.log("isLoggedIn: " + isLoggedIn); // undefined!
if (isLoggedIn == 0 || isLoggedIn == -1) {
$location.path('/app/landing');
}
else {
$scope.errorMessage = "Invalid login data!";
}
};
是的,问题似乎是异步的。如果你想访问登录方法的结果,你应该向它传递一个回调。因为在您调用它之后,下一次执行将是您的控制台日志,并且会在您的 SQL 查询 returns 结果之前发生。