我有一个登录页面,用于向登录控制器提交用户凭据。 但在授权用户之前,我需要打开"打开"会话并接收有效的会话ID。
我的主要问题是在下面的this.openUserSession
API 调用中处理错误事件。也就是说,我在$q.reject()
事件中返回了$http.error()
,但它并没有像我预期的那样在堆栈中冒泡。
以下是流程:
1)用户输入凭据并单击"登录"按钮,调用LoginCtrl
函数loginUser()
2)我立即打电话给userService.initUserSession
以获得有效的会话ID。
3)如果成功,请致电loginService.authUser
4)如果sessionID无效,那么我需要返回$q.reject
并显示消息
"无法打开用户会话"
*****代码详情*****
请注意,首先是我" init" that.initRzr
中的应用,然后我在下方拨打that.openUserSession
:
this.initUserSession = function initSession($rootScope, username) {
var deferred = $q.defer();
deferred.notify("Establishing Session ID...");
$rootScope.userID = username;
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRzr(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
// ******** OPEN USER SESSION ***********
that.openUserSession(razorEnvJson).then(function (data) {
// ... some code omitted here.
deferred.resolve(sessionID);
return sessionID;
});
}
}, function (error) {
// *** I NEVER HIT LINE !!! ***
deferred.reject('Could not open user session.');
});
});
return deferred.promise;
}

**** OPEN USER SESSION ***
注意:我在这里点击.error()
代码,因为我可以看到控制台记录的消息"无法通过api cal打开用户会话..."。但是,处理似乎停在此处,我的登录屏幕只是使用微调器图标冻结。
this.openUserSession = function (razorEnvParams) {
// init some variables here...
var url = "http://" + _domain + ":" + _port + controllerpath + "?userid=" + user + "&pass=" + pass;
var deferred = $q.defer();
deferred.notify("Opening user session...");
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
console.log("Cannot open a user session via api call. Errors details: " + data);
deferred.reject("Could not open a user session.");
});
return deferred.promise;
}

如果不清楚,我会尝试改进这篇文章。请指教......
提前感谢。
鲍勃
****更新****
根据JB Nizet的回答,我错过了that.openUserSession
的错误回调。我在下面添加了function(error)
,它按预期工作。
我现在将继续讨论JB发布的链接建议。
this.initUserSession = function initSession($rootScope, username) { // ESTABLISH A RAGE CONNECTION AND SESSION ID !
var deferred = $q.defer();
deferred.notify("Establishing Rage Session ID...");
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRazor(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
that.openUserSession(razorEnvJson).then(function (data) {
deferred.resolve(sessionID);
return sessionID;
}, function (error) {
deferred.reject('Could not open user session.');
});
}
}, function (error) { // **** ADDED ERROR HANDLING ***
deferred.reject('Could not initial a user session.');
});
});
return deferred.promise;
}

答案 0 :(得分:2)
openUserSession()
失败,并且您没有针对该失败进行任何错误回调,因此承诺永远不会被解决也不会被拒绝。
这个错误,以及大量的重复,是由您使用promise antipattern引起的。改为使用链接:
that.getRazorInitParams()
.then(that.initRzr)
.then(that.openUserSession)
.catch(function() { ... });
无需创建延迟并解决它。只需使用链接。例如,openUserSession()
可以替换为
this.openUserSession = function (razorEnvParams) {
var url = "http://" + _domain + ":" + _port + controllerpath;
return $http({
method: 'POST',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url,
params: {
userid: user,
pass: pass
}
}).then(function (response) {
return response.data;
});
}
此外,永远不要使用GET来传输秘密凭据:它们将以纯文本形式存储在各种日志中。永远不要连接参数。必须对它们进行编码,Angular会使用params
为您执行此操作。