链接多个承诺(处理回调)
当承诺涉及到多个承诺时,我遇到了一些困难。这种混乱是有区别如何正确利用承诺 &他们与回调差异优势。我注意到,无论承诺是否解决,有时会触发回调,从而使得下面的实现不可靠。(除非我的语法&逻辑错误)
我阅读了官方文档并提出了这个问题,但我不确定它是否正确实现。
该注册流程如下:
链接多个承诺(处理回调)
- 用户选择一个别名 - >详细别名+用户ID(设备的通用唯一标识符)被发送服务器侧
- 如果别名是可用的产生,ApiKey(令牌) ,用户注册,并发送回客户端侧(DB存储)
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)
- 无论何时该承诺已被解决或将被解决或被拒绝,只要结果可用,就会异步调用其中一个成功或错误回调。回调被调用一个参数:结果或拒绝原因。另外,在承诺被解决或被拒绝之前,通知回叫可以被称为零次或多次以提供进度指示。
- 什么是具有回调,如果他们可以,如果承诺得到解决,无论火点?
- 在第一个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');
});
}]);
注:我知道这是一个不好的做法来存储信息的客户端,但是,我经过不同的概念(匿名消息),并没有安全问题。
感谢您的时间
你的第二个,然后调用似乎不正确,后
//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传递,您的失败函数作为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现在是一个功能块内,并承诺从随后封锁您想从链返回。
我觉得$q.serial是一个很好的链接承诺库。这很容易使用,并处理很多事情,比如检查链上的所有承诺是否真的有承诺。
这里是一个小例子:
function do_all() {
var task_1 = function() {
return $http.get("some url")
.then(on_xhr_completed_fn, on_xhr_failed_fn);
}
var task_2 = function(some_data) {
vm.bla = some_data;
return $http.get("other url")
.then(on_xhr_completed_fn, on_xhr_failed_fn);
}
var task_3 = function(other_data) {
vm.bli = other_data;
}
var tasks = [task_1, task_2, task_3];
return $q.serial(tasks)
.then(function() {
console.log("Finished tasks 1, 2 and 3!!!");
});
}
所以,如果我理解正确的,这里Promise1接受3个参数,并返回承诺RegDevice是成功的回调(放置在第一arugment内) – Awena 2014-09-24 03:00:28
它完美,事件被同步触发,先Promise1然后是2.第二个then()[函数(d)成功/函数(e)错误promise2的回调?因此,如果我有3个承诺,我会在函数(d)返回中调用第三个...等等 – Awena 2014-09-24 03:11:37
这是正确的。 – 2014-09-28 22:29:12