如何在两个连续的角度服务呼叫期间中止/取消第一个呼叫的承诺
How to abort/cancel promise for first call during 2 consecutive angular service calls?
当在下拉项选择上通过$http angular service进行两次连续的服务调用时,假设第一次调用需要时间才能返回,第二次调用在第一次调用解析之前返回,则它会显示第二项选择的第一次调用的数据。
所以,如果在第一次调用解析之前再次进行服务调用,是否有任何方法可以中止第一次承诺。
为了演示的目的,我创建了一个示例plunkar,它有几个项目的下拉列表,我添加了明确的条件,在选择第一个项目时,它比其他项目花费的时间要长一些。所以选择第一个项目并立即选择第二个项目来再现场景,检查屏幕上显示的最喜欢的书。
感谢您的帮助!
服务代码:
app.factory('bookService', function($http, $q, $timeout) {
return {
getBook: function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}));
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise.promise;
}
}
});
我找到了两种方法来处理这种情况-
案例1:在服务级别创建全局$q deffer对象,并在调用$http请求之前检查该对象是否有值。如果这个deffer对象有值,那么显式解析它。Plunkar代码-代码片段
服务代码:
app.factory('bookService', function($http, $q, $timeout, bookConstants) {
var service = {};
service.mypromise = null;
service.getBook = function(id) {
if (service.mypromise) {
service.mypromise.resolve(bookConstants.EXPLICIT_CANCEL);
service.mypromise = null;
}
service.mypromise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
if (service.mypromise) {
service.mypromise.resolve(data.filter(function(obj) {
service.mypromise = null;
return obj.id == id
}))
}
}, timeoutSpan);
}).error(function(msg) {
service.mypromise.reject(msg);
})
return service.mypromise.promise;
}
return service;
});
情况2:返回$q deffer对象作为服务响应,并将其维护在控制器级别。在连续服务调用的情况下,首先检查并明确解决第一个服务调用,然后继续其他服务调用。Plunkar代码-代码片段
示例代码:
$scope.getSelectedValue = function() {
var id = $scope.selitem.id
$scope.cancel();
var bookPromise = bookService.getBook(id);
$scope.requests.push(bookPromise);
bookPromise.promise.then(getBookSuccess)
.catch(errorCallback)
.finally(getBookComplete);
}
function getBookSuccess(favouriteBooks) {
if (favouriteBooks == 'User Cancelled') {
return;
}
var books = '';
angular.forEach(favouriteBooks, function(book) {
books += book.bookName + ' '
});
$scope.selectedvalues = 'Name: ' + $scope.selitem.name +
' Id: ' + $scope.selitem.id + ' Favourite Book(s): ' + books;
}
function errorCallback(errorMsg) {
console.log('Error Message: ' + errorMsg);
}
function getBookComplete() {
console.log('getBook Has Completed!');
}
$scope.cancel = function() {
if ($scope.requests) {
angular.forEach($scope.requests, function(request) {
request.resolve('User Cancelled');
clearRequest(request);
})
}
};
var clearRequest = function(request) {
$scope.requests.splice($scope.requests.indexOf(request), 1);
};
}]);
app.factory('bookService', function($http, $q, $timeout) {
var service = {};
service.getBook = function(id) {
var promise = $q.defer();
var timeoutSpan = id == 1 ? 3000 : 500;
$http.get("favouriteBooks.json").success(function(data) {
$timeout(function() {
promise.resolve(data.filter(function(obj) {
return obj.id == id
}))
}, timeoutSpan);
}).error(function(msg) {
promise.reject(msg);
})
return promise;
}
return service;
});
您可以使用以下命令等待两个或多个承诺$q.all([promise1,promise2]).then(function(data){....});
要访问第一个promise的数据,只需使用data[0]
,第二个promise返回值保存在data[1]
中,依此类推…
相关文章:
- 我的职位回报太快了,如何做出承诺
- 打破承诺链的好方法是什么
- 从函数返回角度承诺
- 我怎样才能获得承诺的价值
- 延期承诺值未更新/解析/延期
- 在承诺链中处理早期回报的最佳方式
- 承诺在非节点式回调上使用Bluebird
- 简单的ES6承诺问题-交换解决和拒绝参数
- 组合承诺和非承诺值
- 带有对象/原型的链式承诺(Q延期)
- AngularJS$q承诺使用socket.io
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- 当一些承诺失败时,如何继续使用$q.all()
- Nodejs和express路由,如何处理客户端的承诺
- 如何在多承诺链中处理谷歌地图API V3事件
- 承诺合并流
- JavaScript承诺-无法读取属性'那么'的未定义
- 等待循环调用的所有承诺完成
- Pg承诺性能提升:在冲突中
- 如何在两个连续的角度服务呼叫期间中止/取消第一个呼叫的承诺