代码之家  ›  专栏  ›  技术社区  ›  bob.mazzo

返回$q的问题。拒绝$http。错误事件

  •  0
  • bob.mazzo  · 技术社区  · 9 年前

    我有一个向登录控制器提交用户凭据的登录页面。 但在授权用户之前,我需要“打开”一个会话并接收一个有效的会话ID。

    然而,我的主要问题是处理 this.openUserSession 美国石油学会 在下面打电话。也就是说,我要返回 $q.reject() $http.error() 事件,但它没有像我预期的那样在堆栈中冒泡。

    以下是流程:

    1) 用户输入凭据并单击“登录”按钮,该按钮将调用 LoginCtrl 作用 loginUser()

    2) 我马上打电话给 userService.initUserSession 以获取有效的会话ID。

    3) 如果成功,请致电 loginService.authUser 4) 如果sessionID无效,则需要返回 $q.reject 并显示消息 “无法打开用户会话”

    *****代码详细信息*****

    请注意,首先我在 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;
    }

    ****打开用户会话***

    注意:我正在打 .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;
    }
    1 回复  |  直到 9 年前
        1
  •  2
  •   JB Nizet    9 年前

    openUserSession() 失败,并且您没有针对该失败的任何错误回调,因此承诺永远不会被解决或拒绝。

    这个bug和大的重叠是由您使用 promise antipattern 。请改用链接:

    that.getRazorInitParams()
        .then(that.initRzr)
        .then(that.openUserSession)
        .catch(function() { ... });
    

    无需创建延迟并解决它。只要用链子。例如 打开用户会话() 可以替换为

    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 .