束缚多个promise(处理回调)

问题描述 投票:1回答:3

当涉及到多个诺言时,我在诺言方面遇到一些困难。困惑在于如何正确利用promises及其与Callbacks的区别。我注意到回调有时会触发,无论承诺是否得到解决,都会使下面的实现不可靠。(除非我的语法和逻辑错误)我阅读了官方文档并提出了建议,但是我不确定它是否实现良好。注册流程如下:

  • 用户选择别名->详细信息别名+ userID(设备的通用唯一标识符)被发送到服务器端
  • 如果可用别名,则生成ApiKey(令牌),用户注册并发送回客户端(存储在数据库中)

Services.js

(function(angular) {
   myApp.factory("deviceDB.Service", ['$resource', '$http', '$q',
   function ($resource,  $http , $q ) {

    return {

//Second Promsie : After API token is generated server-side, store res in db

        RegDevice: function (alias, apiKey, userID) { 
            var deferred = $q.defer();
            var configuration ;
            var db = window.sqlitePlugin.openDatabase({name: "config.db"});
            setTimeout(function () {

                db.transaction(function (tx) {
                    tx.executeSql('CREATE TABLE IF NOT EXISTS user_details (userID UNIQUE , alias TEXT, apiKey TEXT)');
                    tx.executeSql("INSERT INTO user_details (userID, alias, apiKey) VALUES (?,?,?)", [userID, alias, apiKey], function (tx, res) {

                        deferred.resolve(configuration = true);
                    }, function (e) {
                        // console.log("ERROR: " + e.message);
                        deferred.reject(configuration = false);
                    });
                });

            }, 1000);
            return deferred.promise;
        },

//First Promsie: Register user  server side & generate APi token

        RegUser: function (alias, userID) { 

            var deferred = $q.defer();
            var pro;
            pro = $resource('api/query/register', {'alias': alias, 'userID': userID},
                { query: {
                        isArray: false,
                        method: 'GET'  } });

            setTimeout(function () {
                pro.query(function (res) {
                    if (res.error) {
                        deferred.reject( { error : res.error, exists: res.exists,  msg: res.message } );
                    }
                    else {
                        deferred.resolve( {error : res.error , alias: res.alias , apiKey: res.apiKey, msg: res.message } );
                    }
                }, function (e) {
                    deferred.reject( { errorStatus: e.status } );

                });

            }, 1000);
            return deferred.promise;
        }

    };

  }]);

}(window.angular));

现在,在“我的控制器”中,我希望将上述两个诺言链接起来。我从文档中引用以下内容:

then(successCallback, errorCallback, notifyCallback) –无论何时,或将何时解决或拒绝承诺,然后只要结果可用,就异步调用成功或错误回调之一。使用单个参数调用回调:结果或拒绝原因。另外,在解决承诺或拒绝承诺之前,通知回调可能被调用零次或多次以提供进度指示。

  1. 无论是否解决Promise,都可以触发Callbacks有什么意义?
  2. 我不应该在第一个Promise的成功回调中打电话给Promise2吗?如果无论是否解析了[[Promise1都将其触发,那么我如何才能以一种触发方式链接Promise2 仅在Promise1被解析时
我试过的:

Controller.js

myApp.controller('RegisterController', ['$scope', '$http', 'deviceDB.Service', function ($scope , $http , deviceDB.Service) { var Promise1 = deviceDB.RegUser($scope.alias, $scope.Device); // First promise - Validate with server Promise1.then(function(data) { console.log(' Registration Server-Side successfully'); $scope.apiKey = data.apiKey; term.echo(data.apiKey); }, function(e) { console.log('Registration Failed'); term.echo(e.msg); }) //Call Promise 2 & Store details Client-Side using .then() .then(deviceDB.RegDevice($scope.alias, $scope.apiKey, $scope.Device), function(d){ console.log('Items Stored in DB successfully'); }, function() { console.log('Items Stored in DB Failed'); }); }]);
注:我知道在客户端存储详细信息是一种不好的做法,但是,我追求的是一个不同的概念(匿名消息传递,并且没有安全方面的顾虑。。

感谢您的时间

javascript angularjs promise angular-promise
3个回答
1
投票
之后您的第二个呼叫似乎不正确,>

//Call Promise 2 & Store details Client-Side using .then()

[then最多接受3个参数then(successCallback, errorCallback, notifyCallback),您正在传递它:deviceDB.RegDevice($scope.alias, $scope.apiKey, $scope.Device),它立即被评估,返回的诺言作为成功函数传递给函数then,您的成功函数作为errorCallback和您的fail函数作为notifyCallback传递。 

我会尝试以下操作

Promise1.then(function(data) { console.log(' Registration Server-Side successfully'); $scope.apiKey = data.apiKey; term.echo(data.apiKey); return deviceDB.RegDevice($scope.alias, $scope.apiKey, $scope.Device) }, function(e) { console.log('Registration Failed'); term.echo(e.msg); return e; }).then(function(d) {/*all good*/}, function(e) {/* all bad */}

注意,现在对RegDevice的调用位于功能块内,并且从要链接的then块中返回了promise。 

0
投票
我发现$q.serial一个很好的链接诺言的库。它非常易于使用,可以处理很多事情,例如检查链上的所有承诺是否都是真正的承诺。

0
投票
以下是使用异步/等待的方法,可能会有所帮助:
© www.soinside.com 2019 - 2024. All rights reserved.