当涉及到多个诺言时,我在诺言方面遇到一些困难。困惑在于如何正确利用promises及其与Callbacks的区别。我注意到回调有时会触发,无论承诺是否得到解决,都会使下面的实现不可靠。(除非我的语法和逻辑错误)我阅读了官方文档并提出了建议,但是我不确定它是否实现良好。注册流程如下:
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)
–无论何时,或将何时解决或拒绝承诺,然后只要结果可用,就异步调用成功或错误回调之一。使用单个参数调用回调:结果或拒绝原因。另外,在解决承诺或拒绝承诺之前,通知回调可能被调用零次或多次以提供进度指示。
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');
});
}]);
注:我知道在客户端存储详细信息是一种不好的做法,但是,我追求的是一个不同的概念(匿名消息传递,并且没有安全方面的顾虑。。感谢您的时间
//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。