我有一个指令,如果显示,将调用一个服务,该服务将返回一个承诺,在内部对服务器进行http调用。
该指令用于每一行,因此,如果我有200行,该指令将被调用200次,这将调用服务200次,这将调用服务器200次。
是否有办法加入对服务的所有调用,以便服务只对服务器进行一次调用,或者多次批量调用,然后通过承诺将特定数据返回给每个指令?
Plnkr示例:https://plnkr.co/edit/Sz5W27mirXKER49ORZvo?p=preview
var app = angular.module('plunker', [])
.service('Service', function($http, $q) {
this.getStatus = function(id) {
var status = $q.defer();
// Obviously, this call is never really made on plnkr.com but it shows the issue
$http({
url: 'https://httpbin.org/get',
method: 'GET',
params: {
id: id
}
}).then(function successCallback(response) {
status.resolve(response.data.args.id);
}.bind(this), function errorCallback() {
status.reject();
}.bind(this));
return status.promise;
};
})
.directive('directive', function() {
return {
restrict: 'E',
replace: true,
template: '<span>{{ status }}</span>',
scope: {
id: "=",
},
controller: function($scope, Service) {
$scope.status = '';
Service.getStatus($scope.id).then(function (status) {
$scope.status = "status" + status;
});
}
}
})
.controller('MainCtrl', function($scope) {
$scope.users = [];
for (var i = 0; i < 200; i++) {
$scope.users.push({id : i, name : 'name' + i});
}
});
答案 0 :(得分:0)
我发现一个有用的方法是让服务保存异步调用返回的promise,并为后续调用返回该promise(如果存在)。一旦对服务器的异步调用完成,清除已保存的promise,以便对服务的任何后续请求将再次调用服务器。
https://plnkr.co/edit/TXUBV10xOsRl9nscRmRl?p=preview
.service('myService', ['$http', function($http){
var serverCall = null;
var callCount = 0;
return {
callAsync: callAsync
};
function callAsync(){
if(serverCall == null){
serverCall = $http({method: 'GET', url: 'https://httpbin.org/delay/3? callCount=' + ++callCount})
.then(function(response){
serverCall = null;
return response.data.args;
});
}
return serverCall;
}
}])
答案 1 :(得分:0)
现在,指令可以向服务发送请求,该服务将它们分组到一个http请求上,并将响应发送回每个指令。每个指令都会收到请求的结果,但现在,只有1个请求,而不是200个请求。
.service('Service', function($http, $q) {
this.cargo = async.cargo(function(tasks, callback) {
var ids = [];
for (var i = 0; i < tasks.length; i++) {
ids.push(tasks[i].id);
}
$http({
url: 'https://httpbin.org/get',
method: 'GET',
params: {
ids: ids
}
}).then(function successCallback(response) {
for (var i = 0; i < tasks.length; i++) {
tasks[i].q.resolve(response.data.args.ids[i]);
}
}.bind(this), function errorCallback() {
for (var i = 0; i < tasks.length; i++) {
tasks[i].q.reject();
}
}.bind(this));
});
this.getStatus = function(id) {
var q = $q.defer();
this.cargo.push({q: q, id: id})
return q.promise;
};
})