【问题标题】:How to use a promise from an jQuery ajax call in Angular如何在 Angular 中使用来自 jQuery ajax 调用的承诺
【发布时间】:2016-06-10 06:04:47
【问题描述】:

我正在尝试按如下方式使用 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

【问题讨论】:

  • 您能否粘贴checkUserlogin 的代码大纲,了解返回的内容和时间很重要。正如下面的答案所述,它假设它是一个新的承诺,但不可能从你的问题中知道。

标签: javascript jquery angularjs ajax promise


【解决方案1】:

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

$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');
});

如果它们不返回 Promise,请修改它们以使其返回(但避免使用 Promise 构造函数),然后上面的代码将起作用。

【讨论】:

  • 如果检查失败,也应该拒绝 checkUserLogin 承诺。
  • 我已根据您的回答编辑了帖子。你能看看并告诉我有什么问题吗
  • @Patrick 您需要修改您的checkUserlogin,以便它返回一个 Promise,当检查完成并成功时应该解决它,如果检查失败则拒绝。
  • 我没有得到它返回承诺的期限。能否请您在 checkUserlogin 函数中显示一个示例?
  • 我添加了checkUserlogin功能代码。你能告诉我如何返回一个在检查完成并成功时解决的承诺,并在检查失败时拒绝它
【解决方案2】:

修改你的检查函数,如果你没有登录则返回一个promise并抛出,如果你登录则返回用户。

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);
});

【讨论】:

  • 嗨,它给出了一个错误。未捕获无法在控制台登录。
  • 这个答案就差不多了。但它在最后阶段给出错误。在控制台未捕获“无法登录”。任何输入胜利?
  • 当访问被拒绝时,函数(错误)应该执行并且它应该指向 BlockUser.html 页面。如果我看到控制台日志,上面给出的 checkUserlogin 函数会抛出一个错误,指出未捕获无法登录
  • 我更新了它,如果未登录则返回 null,以便我们检查。现在只有错误才会调用最终承诺的拒绝状态。
【解决方案3】:

假设 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');
    });
});

【讨论】:

    猜你喜欢
    • 2014-06-14
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    相关资源
    最近更新 更多