Javascript 在处理结果之前,等待承诺完成
我有一个包装第三方API的服务,我正在使用它将数据检索到我的控制器中。我想在显示数据之前对数据进行一些处理,但我无法在承诺完成后实现这一点。在此之前,没有数据可处理 我尝试了几种不同的方法,但似乎都不管用:Javascript 在处理结果之前,等待承诺完成,javascript,angularjs,promise,Javascript,Angularjs,Promise,我有一个包装第三方API的服务,我正在使用它将数据检索到我的控制器中。我想在显示数据之前对数据进行一些处理,但我无法在承诺完成后实现这一点。在此之前,没有数据可处理 我尝试了几种不同的方法,但似乎都不管用: angular.module('myApp').controller('myController', function ($scope, MyService) { $scope.getData = function () { MyService.getData(myP
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;
}
}
}]);
这肯定是一件很常见的事情,但我在谷歌上找不到太多东西——尽管我可能在搜索错误的东西
编辑
好的,我已经重构了很多东西,而潜在的问题似乎仍然是,我的承诺链在从链的早期返回数据之前正在进行。以下是新代码:
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中的注释),然后将其传递回控制器显示。如果有什么不清楚的地方,我很乐意添加更多的评论
(对于架构方面的任何一般性反馈,我们都将不胜感激!)所以我完全重构了一切,现在一切都正常了!其中一个问题是忘记了
$q.resolve()
和$q.reject()
只能返回一个参数,而我假设我可以使用它们返回任意多的参数(就像使用匿名函数一样),以后调用then()
将接收所有参数
如果有人感兴趣,我会在重构后发布我的代码,但我至少需要做的是替换如下调用:
operation.resolve(arg1, arg2, arg3);
为此:
operation.resolve({'arg1': arg1, 'arg2': arg2, 'arg3':arg3});
并相应地调整接受这些参数的函数。“这只在
$scope.queryResults=results处触发;
”正是您想要的,不是吗?如果results
是一个空数组,那么这意味着getData
确实导致了一个空数组。我猜是你的服务做了一些奇怪的事情,或者你只是没有收到你请求的任何数据。它确实返回数据,但需要几秒钟的时间<代码>然后(函数(结果){$scope.queryResults=results;}立即被一个空数组调用,然后在底层API调用完成后填充该数组。因此,MyService.getData返回了错误的承诺。如果您可以为它发布代码,它可能会揭示发生这种情况的原因。显然ThirdPartyLibrary.getData
不会做您认为它会做的事情-任何信息从图书馆出去?