【发布时间】:2015-12-11 10:16:01
【问题描述】:
我有一个包装了第 3 方 API 的服务,我用它来将数据检索到我的控制器中。我想在显示数据之前进行一些处理以对数据进行透视,但我不知道如何在承诺完成后实现这一点。。在那之前没有数据需要处理!
我尝试了几种不同的方法,但似乎都不起作用:
angular.module('myApp').controller('myController', function ($scope, MyService) {
$scope.getData = function () {
MyService.getData(myParams)
.then(function (results) {
$scope.queryResults = results;
// Can't do processing here, data hasn't been retrieved yet
}, function (err) {
$scope.alerts.push({ msg: 'Unable to get data', type: 'danger' });
});
}
$scope.$watch('queryResults', function(newVals) {
// Can't do processing here either, this only fires at
// "$scope.queryResults = results;"
// above where "results" is still an empty array
});
};
还有服务:
angular.module('myApp').service('MyService', ['$q', function($q) {
return {
getData: function (params) {
var operation = $q.defer();
ThirdPartyLibrary.getData(params, { callback: function(err, results) {
if (err == null ) {
operation.resolve(results);
} else {
operation.reject(err, results);
}
}});
return operation.promise;
}
}
}]);
这一定是一件很常见的事情,但我在 Google 上找不到很多东西 - 尽管我可能正在寻找错误的东西!
编辑
好的,所以我已经重构了很多东西,而潜在的问题似乎仍然是我的 Promise 链在从链中的早期返回数据之前正在进展。这是新代码:
angular.module('myApp').service('MyService', ['MyWrapperService', function(MyWrapperService) {
var getDataForFilter = function(myApi, filter) {
var processedResults = {};
// This is the chain I'm having problems with
return MyWrapperService.getRelevantKeys(myApi, filter).then(MyWrapperService.getDetailsForKeys).then(function(results){
//do some processing here
return processedResults;
}, function(errors) {
return errors;
});
};
return {getDataForFilter: getDataForFilter};
}]);
angular.module('myApp').service('MyWrapperService', ['$q', function($q) {
var getRelevantKeys = function(myApi, filter) {
var operation = $q.defer();
myApi.getKeys({'filter': filter, 'callback': function (err, results) {
if (err == null) {
// This does get called correctly, but not until after the rest of the chain has been called.
operation.resolve(myApi, results, filter);
} else {
operation.reject(err, results);
}
}
};
var getDetailsForKeys = function(myApi, keys, filter) {
var operation = $q.defer();
var promises = [];
var details = [];
var errors = [];
angular.forEach(keys, function (val) {
// Get the data for each key. ***When this is called, 'keys' is still undefined.***
promises.push(getDataForKey(myApi, val, filter).then(function(result){
details.push(result);
}, function(err, result) {
errors.push(err);
}));
});
$q.all(promises).then(function() {operation.resolve(details);}, function() {operation.reject(errors)});
return operation.promise;
};
var getDataForKey = function(myApi, key, filter) {
var operation = $q.defer();
myApi.getDetail(key, {
'filter': filter,
'callback': function(err, results) {
if (err == null) {
operation.resolve(myApi, results, activity);
} else {
operation.reject(err, results);
}
}
});
return operation.promise;
};
return {
getRelevantKeys: getRelevantKeys,
getDetailsForKeys: getDetailsForKeys,
getDataForKey: getDataForKey,
};
}]);
不幸的是,API 让我想做的事情有点冗长,但我正在获取与过滤器相关的所有数据库键,然后获取这些键的所有值,然后旋转数据(评论在getDataForFilter) 中,然后将其传递回控制器进行显示。如果有什么不清楚的地方,我很乐意添加更多的 cmets。
(也非常感谢任何有关架构的一般性反馈!)
【问题讨论】:
-
"这只会在
$scope.queryResults = results;触发" 正是你想要的,不是吗?如果results是一个空数组,那么这意味着getData确实导致了一个空数组。 -
我猜是您的服务做了一些奇怪的事情,或者您实际上并没有收到您提出的请求的任何数据。
-
它确实会返回数据,但需要几秒钟才能发生。
then(function (results) { $scope.queryResults = results; }会立即使用一个空数组调用,然后在底层 API 调用完成后填充该数组。 -
那么 MyService.getData 返回错误的承诺。如果您可以发布它的代码,它可能会揭示它发生的原因。
-
显然
ThirdPartyLibrary.getData没有做你认为它做的事情 - 关于那个图书馆的任何信息?
标签: javascript angularjs promise