如何在Angular中使用来自jQuery ajax调用的promise

时间:2016-06-08 20:55:52

标签: javascript jquery angularjs ajax promise

我正在尝试使用承诺如下......

 $q.when().then(function () {
    return $rootScope.$emit('resetView', false, 'default');
}).then(function (result) {
    $log.info('login id loaded');   //execute this one first
    checkUserlogin();
}).then(function (result) {
    $log.info('Layout loaded');     //execute this one only when 1st is success. If 1st is failed, dont execute this one.
    loadData();
}, function (error) {
    $log.error("Caught an error:", error);
    return $q.reject('New error');
});

如您所见,我有2个要执行的功能。 checkUserLogin()和loadData()。

在checkUserLogin()中,我们检查是否允许用户访问。用户ID被获取并通过ajax传递给后端。数据库已检查。如果存在访问权限,则应执行loadData()。如果不存在访问,则不应执行loadData()。

目前,这种情况正在发生。 checkUserLogin()被执行。用户ID通过ajax传递给后端。直接loadData()被执行。现在加载页面后,ajax返回调用并获知用户无权访问。他被重定向到访问被拒绝的页面。

我不希望这种情况发生。只有在确认用户有权访问后才能进行页面加载。知道如何实现这个目标吗?

编辑(根据Paulpro的答案)

$q.when().then(function () {
return $rootScope.$emit('resetView', false, 'default');

}).then(function (result) {
$log.info('checkuser loaded');   //execute this one first
return checkUserlogin();

}).then(function (result) {
$log.info('Layout loaded');     //execute this one only when 1st is success. If 1st is failed, dont execute this one.
return loadData();

}, function (error) {
$log.error("Caught an error:", error);
return $q.reject('New error');
});


var checkUserlogin = function() {
$log.info(' Inside Login check function executed');  
 var serviceURL_CheckUserExists = '/api//CheckUserExists';

    //ajax to check if user exists in database. give/ deny access based on user present in DB and if user is set as blockuser in db. 
    $.ajax({
        type: "GET",
        url: serviceURL_CheckUserExists,
    }).then(function (response) {
        if (response.Results.length == 1 && response.Results[0].BlockUser == false) {
            $rootScope.myLayout.eventHub.emit('getUserName', response.Results[0].User_ID.trim());

            });
        }
        else { $window.location.href = '../../../BlockUser.html'; }
}

按照上面的编辑 - 这里是当前正在执行的步骤。 $ log.info给出如下输出。

checkuser loaded
Layout loaded
Inside Login check function executed

实际上,这些应该是步骤。

checkuser loaded
Inside Login check function executed
Layout loaded

3 个答案:

答案 0 :(得分:2)

您传入的函数应该返回另一个Promise,否则对then的调用将返回一个立即解析的promise(对于函数的返回值,在您的情况下为undefined)。您希望返回在ajax调用完成之前无法解析的promise。假设checkUserLogin();loadData();都返回promise,你只需要添加几个return语句:

$q.when().then(function () {
    return $rootScope.$emit('resetView', false, 'default');
}).then(function (result) {
    $log.info('login id loaded');   //execute this one first
    return checkUserlogin();
}).then(function (result) {
    $log.info('Layout loaded');     //execute this one only when 1st is success. If 1st is failed, dont execute this one.
    return loadData();
}, function (error) {
    $log.error("Caught an error:", error);
    return $q.reject('New error');
});

如果他们没有返回promises,那么修改它们就可以了(但是避免使用Promise构造函数),然后上面的代码就可以了。

答案 1 :(得分:1)

假设checkUserlogin返回一个承诺,请尝试...

$q.when().then(function() {
    return $rootScope.$emit('resetView', false, 'default');
}).then(function(result) {
    $log.info('login id loaded'); //execute this one first
    checkUserlogin().then(function(result) {
        $log.info('Layout loaded'); //execute this one only when 1st is success. If 1st is failed, dont execute this one.
        loadData();
    }, function(error) {
        $log.error("Caught an error:", error);
        return $q.reject('New error');
    });
});

答案 2 :(得分:1)

修改您的检查功能以返回一个承诺,如果您已登录则退出并返回用户。

var checkUserlogin = function() {
 $log.info(' Inside Login check function executed');  
 var serviceURL_CheckUserExists = '/api/CheckUserExists';

    //ajax to check if user exists in database. give/ deny access based on user present in DB and if user is set as blockuser in db. 
 return $.ajax({
        type: "GET",
        url: serviceURL_CheckUserExists,
 }).then(function (response) {
   if (response.Results.length == 1 && response.Results[0].BlockUser == false) {
     return response.Results[0].User_ID.trim();
   }
   else 
   { 
     return null; // could not login
   }
 });
}

此时你可以做到

$q.when().then(function () {
    return $rootScope.$emit('resetView', false, 'default');
}).then(function (result) {
    $log.info('login id loaded');   //execute this one first
    return checkUserlogin();
}).then(function (result) {
    $log.info('Layout loaded');     // execute this when we know if we are logged in or not
   // not logged in
   if (result === null) {
      $window.location.href = '../../../BlockUser.html';
      return;
    }

    // we have a good user so emit
    $rootScope.myLayout.eventHub.emit('getUserName', result);
    // finally load data
    loadData();
}, function (error) { // redirect on blocked user
    $log.error("Caught an error:", error);
});