AngularJS 将 cordova 权限包装到承诺链中?

AngularJS wrapping cordova permissions into a promise chain?

就在我认为我的脑子里全是承诺时,我试图实现一些东西,但以一种让我意识到我还没有完全理解 Angular 的方式跌跌撞撞。

啊!

我正在初始化我的应用程序并创建一个初始化控制器和服务工厂,以要求用户设置应用程序所需的权限。但是,在 .factory 中,我不知道如何正确创建承诺序列。我想按顺序询问用户,从而创建一个承诺链。

Promise 1 = ask for sms access
   process 1 results
   Promise 2 = ask for GET_ACCOUNTS
      process 2 results
      Promise 3 = ask for GPS
         process 3 results
         return to controller with all results

第一个 Promise 让我失望,因为我正在使用的插件 returns 在请求用户权限时异步:

function requestReadPermission() {  // from cordova-plugin-sim
// no callbacks required as this opens a popup which returns async
  window.plugins.sim.requestReadPermission();
}

return $q(requestReadPermission)
.then(function(status) {
   console.log(status) ; // just see what comes back 
   // do something with status
   function getAccounts() {
      cordova.plugins.diagnostic.requestContactsAuthorization() ;
   }
   return $q(getAccounts)
}).then(function(status) {
   console.log(status) ; // just see what comes back 
   // do something with status
   function getGPS() {
      cordova.plugins.diagnostic.requestLocationAuthorization() ;
   }
   return $q(getGPS)
}).then(function(status) {
   console.log(status) ; // just see what comes back 
   // do something with status
   return allResults ;
})

此外,后两个承诺看起来已经是回调函数了……所以我不知道我是否可以按照我想要的方式实现它们。它们来自 cordova-plugin-diagnostics,在文档中的调用方式如下:

cordova.plugins.diagnostic.requestContactsAuthorization(function(status){
    if(status === cordova.plugins.diagnostic.permissionStatus.GRANTED){
        console.log("Contacts use is authorized");
    }
}, function(error){
    console.error(error);
});

cordova.plugins.diagnostic.requestLocationAuthorization(function(status){
    switch(status){
        case cordova.plugins.diagnostic.permissionStatus.NOT_REQUESTED:
            console.log("Permission not requested");
            break;
        case cordova.plugins.diagnostic.permissionStatus.GRANTED:
            console.log("Permission granted");
            break;
        case cordova.plugins.diagnostic.permissionStatus.DENIED:
            console.log("Permission denied");
            break;
        case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
            console.log("Permission permanently denied");
            break;
    }
}, function(error){
    console.error(error);
});

必须向诊断插件函数传递一个回调函数,以接收来自插件本机部分的异步结果。 但是,您可以通过返回由两个异步回调的结果解决的承诺,以使其 Angular 友好的方式包装它。 例如:

function myFunction(){
    var q = $q.defer();
    var statuses = {};
    cordova.plugins.diagnostic.requestContactsAuthorization(function(status){
        console.log('contacts: '+status);
        statuses['contacts'] = status;
        cordova.plugins.diagnostic.requestLocationAuthorization(function(status){
            console.log('location: '+status);
            statuses['location'] = status;
            q.resolve(statuses);
        });
    });
    return q.promise;
}

然后您可以使用 Angular 风格的承诺调用您的包装函数:

myFunction().then(function(statuses){
    for(var permission in statuses){
        console.log(permission+' is '+statuses[permission]);
    }
});