Javascript Angularjs$http使用$q.defer返回未完成的结果
我对angular有一个问题,即结果在实际完成之前返回到我的控制器,即使我正在使用$q.defer功能。我在我的服务中有以下功能Javascript Angularjs$http使用$q.defer返回未完成的结果,javascript,angularjs,angular-promise,angular-http,Javascript,Angularjs,Angular Promise,Angular Http,我对angular有一个问题,即结果在实际完成之前返回到我的控制器,即使我正在使用$q.defer功能。我在我的服务中有以下功能 getFileInfo : function (fulfillmentId) { var pdfResults = []; var jpgResults = []; var orderDetails = {}; var deferred = $q
getFileInfo : function (fulfillmentId)
{
var pdfResults = [];
var jpgResults = [];
var orderDetails = {};
var deferred = $q.defer();
$http.get(appConstants.api_url + '/references/' + fulfillmentId + '/files?max=2000')
. then (function (fileResults)
{
angular.forEach(fileResults.data.entities,function(value)
{
if(value.file.extension == 'pdf')
{
pdfResults.push({files : value});
}
if(value.file.extension == 'jpg')
{
jpgResults.push({files : value});
}
});
orderDetails.jpgResults = jpgResults;
return pdfResults;
})
.then (function (pdfResults)
{
angular.forEach(pdfResults,function(value,key)
{
var fileUuid = value.files.file.file_uuid;
return $http.get(appConstants.api_url + '/resources/' + fileUuid + '/tags')
.then (function (preflightResults)
{
var deserializeJson = [];
deserializeJson.push(angular.fromJson(preflightResults.data.entities[0].resource_json));
var formatedPreflightResults = localAPI.addUIMessages(deserializeJson);
pdfResults[key].preflightResults = formatedPreflightResults;
});
});
orderDetails.pdfResults = pdfResults;
deferred.resolve(orderDetails);
});
return deferred.promise;
}
我从我的控制器上这样叫它:
conformAPI.getFileInfo($scope.fulfillmentId)
.then (function (results)
{
console.log(results);
console.log(results.pdfResults[0]);
console.log(results.pdfResults[0].preflightResults)
});
我遇到的问题是,我做的最后一个控制台日志是未定义的。其他一切结果都很好。第一个和第二个控制台都有preflightResults对象,但它的添加似乎有点晚。我认为使用$q.delay在所有事情完成之前不会返回任何内容。关于如何解决这个问题有什么想法吗?看起来您没有在等待“getFile”get请求的结果。 我重构了你的代码。因为我不能运行它,所以它可能不起作用,但你应该明白我的意思
getFileInfo: function (fulfillmentId) {
var pdfResults = [];
var jpgResults = [];
var orderDetails = {};
var deferred = $q.defer();
function getByFileId(fileUuid, preflightResults) {
return $http.get(appConstants.api_url + '/resources/' + fileUuid + '/tags')
.then(function (preflightResults) {
var deserializeJson = [];
deserializeJson.push(angular.fromJson(preflightResults.data.entities[0].resource_json));
var formatedPreflightResults = localAPI.addUIMessages(deserializeJson);
return formatedPreflightResults;
});
}
function getFiles(pdfResults) {
var subDefer = $q.defer();
var current = 0;
angular.forEach(pdfResults, function (value, key) {
current += 1;
var fileUuid = value.files.file.file_uuid;
getByFileUuid(fileUuid, preflightResults)
.then(function (results) {
pdfResults[key].preflightResults = results;
// need to know when done with all
if (pdfResults.length === current) {
subDefer.resolve(pdfResults);
}
});
});
return subDefer.promise;
}
$http.get(appConstants.api_url + '/references/' + fulfillmentId + '/files?max=2000')
.then(function (fileResults) {
angular.forEach(fileResults.data.entities, function (value) {
if (value.file.extension == 'pdf') {
pdfResults.push({ files: value });
}
if (value.file.extension == 'jpg') {
jpgResults.push({ files: value });
}
});
orderDetails.jpgResults = jpgResults;
return pdfResults;
}).then(getFiles).then(function(pdfResults) {
orderDetails.pdfResults = pdfResults;
deferred.resolve(orderDetails);
});
return deferred.promise;
}您过早地兑现了承诺 由于第一个then()只返回一个对象,因此第二个then()将立即返回。这就是代码所做的(粗略的伪代码): $http.get().then(首先返回$http.get) 一旦启动第一个文件的get,就返回(
return$http.get(appConstants.api_url+
)。此时,只有顶部的第一个$http.get肯定已解析。您可能会看到(第一个文件的)第二个$http.get很快解决,但您还没有启动更多文件的$http.get
如果删除中间的返回以便生成所有$http.get,那么您在这段代码中可能的目标是:
$http.get()。然后(启动所有$http.get并解析承诺)
一旦您遍历了所有文件并使用$http.get启动它们,您就可以解决承诺。这也有同样的问题——承诺解决得太早。所有的get都已发送出去,但您不能确定它们是否已返回
你可以做的是:
$http.get().then(启动所有$http.get并在它们全部完成后解析承诺)
例如,您可以将它们映射到$http.get:filePromises=pdfResults.map(函数(e)$http.get(e))的数组,而不是pdfResults上的forEach
然后您将
返回$q.all(filepromissions)
在您现在已延迟的末尾。解析(orderDetails)。实际上,根据数据的输入方式,我的方法是正确的。啊,因此该值有一个属性“files”…?啊,现在我看到了。您正在分配pdfResults[key].Preflight导致回调。让我给你一个更好的答案。是的,文件是一个属性。这里有一个关于链接承诺的精彩视频: