繁体   English   中英

如何在AngularJS或Javascript中实现类似于C#的等待?

[英]How to achieve something similar to C#'s await in AngularJS or Javascript?

我正在做一个项目,该项目需要我允许我的用户使用我正在使用Google API客户端的Google登录(可以在此处找到参考)。

现在我的代码是这样的。

文件:services / auth-service.js

angular.module('myApp')
  .factory('gapi', function ($q) {

    var auth2;

    gapi.load('auth2', function () {
      auth2 = gapi.auth2.init({
        client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
      });
    });

    return {
      isSignedIn: function () {
        return auth2.isSignedIn.get();
      }
    }
  });

文件:controllers / dashboard.js

angular.module('myApp')
  .controller('DashboardCtrl', function (gapi) {
      alert(gapi.isSignedIn());
  });

现在的问题是,当在dashboard.js文件中运行alert()命令时,此时尚未加载auth2(因为它是通过Internet从Google API加载的),因此我收到了isSignedIn可以的错误信息取消取消定义。

因此,理想情况下,我可能需要的是C#await函数之类的东西,它等待返回值,然后调用该方法。 任何解决方案将不胜感激。 我已经花了数小时尝试诺言和其他方法,但是我无法使它们中的任何一个起作用。

更新:您的大多数答案将在上述情况下工作。 让我们尝试一下这种情况,它更加复杂,应该首先提到。 (对不起)。

文件:scripts / app.js

.state('main', {
   url: '/admin',
   abstract: 'true',
   templateUrl: 'views/main.html',
   resolve: {
     check: function ($q, auth) {
       if(!auth.isSignedIn())
       {
          $q.reject({authenticated: 'false'});
       }
     }
   }
 })
 .state('admin', {
   url: '',
   parent: 'main',
   templateUrl: 'views/admin.html'
 })

现在,如果我在这里使用诺言,那么angular不会等待诺言得到解决。 这将简单地加载视图,并且在加载视图之后调用$ q.reject将毫无用处。

您可以通过以下方式使用promise实现此目的:

文件:services / auth-service.js

angular.module('myApp')
  .factory('gapi', function ($q) {

    var auth2;
    var isSignedInDeferred = $q.defer();

    gapi.load('auth2', function () {
      auth2 = gapi.auth2.init({
        client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
      });
      isSignedInDeferred.resolve(auth2.isSignedIn.get());
    });

    return {
      isSignedIn: function () {
        return isSignedInDeferred.promise;
      }
    }
  });

文件:controllers / dashboard.js

angular.module('myApp')
  .controller('DashboardCtrl', function (gapi) {
      gapi.isSignedIn().then(isSigned) {
          alert(isSigned);
      }
  });

只需更改您的isSignedIn函数即可返回承诺并在您拥有该值时解析该承诺。

该功能在ES7的草稿中可用,如果您感到满意, babel (转译器)将支持async/await 话虽如此,只要保证就可以轻松实现:

gapi.client.load(name, version, callback)

将客户端库接口加载到特定的API。 如果未提供回调,则返回promise 加载的API接口的格式为gapi.client.api.collection.method。 例如,主持人API将创建诸如gapi.client.moderator.series.list之类的方法。

该api已经给了您一个承诺,因此无需将其包装在q ,您要做的就是返回该承诺:

return gapi.load('auth2').then(function() {
    return gapi.auth2.init({
       client_id: '649922003965-ni9e6nad25dh3ejoll70va550kt7cu5u.apps.googleusercontent.com'
    });
});

现在,从您的控制器:

gapi.then(function(auth2){
  //auth2 already loaded
});

编辑:假设您可以在检查功能上获得返回的承诺。 您需要做的只是:

var possiblyRejectedPromise = gapi.then(function(auth2){
   if(!auth2.isSignedIn.get()){
       throw new Error('Not logged in');
   } else {
       //LoggedIn
       return true;
   }
 });
return possiblyRejectedPromise;

ES5中没有等效的await 您需要掌握在事件发生时进行处理并根据这些事件更新应用程序状态的思想。

对于您的特定问题,我相信您的假设是正确的,因为它没有设置auth2变量(因此未定义),因此失败了。 “ auth2未定义”状态是您的代码需要处理的应用程序状态之一。 解决方案可能像更改isSignedIn函数一样简单:

isSignedIn: function () {
    return auth2 && auth2.isSignedIn.get();
}

这样,只有在设置了auth2变量且isSignedIn属性为true时,它才返回true。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM