Angular 循环承诺 - 函数 Returns 空对象
Angular Looping Promises - Function Returns Empty Object
我正在尝试将结果(数组)从 promise 传递到迭代此结果的函数,为每个项目发出 get 请求并在 returning 之前使用结果创建一个新对象它。问题是在解决承诺并填充它之前,正在 returned 对象。从多个承诺中 return 填充对象的正确方法是什么?
function getPackageDetails(packages) {
var detailedPackages = {};
angular.forEach(packages, function(p) {
vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
var subsystem = response.data.packageManifest.subsystem;
var partNumber = response.data.packageManifest.resultConfig.partNumber;
var packageName = response.data.packageMetaData.packageName;
if(detailedPackages[subsystem] === undefined) {
detailedPackages[subsystem] = {};
}
if(detailedPackages[subsystem][partNumber] === undefined) {
detailedPackages[subsystem][partNumber] = {};
}
detailedPackages[subsystem][partNumber][packageName] = response.data;
});
});
return detailedPackages; // returns before all promises resolved
}
vsmsCampaignFactory.getCampaignPackages(queryString)
.then(function(response) {
vm.packageList = getPackageDetails(response.results);
});
对于这样的情况,您应该考虑使用 $q.all
,在这种情况下,您可以将所有承诺收集在单个承诺数组中,然后将其传递给 $q.all
和 return 结果承诺。它将确保您在完成所有承诺后 returning data
。
在您的代码中,您只是在执行异步 ajax 调用,而不用担心它们是否完成。紧接着您正在 returning detailedPackages
数据。但显然它会是空的。
代码
function getPackageDetails(packages) {
var detailedPackages = {};
var promises = []; //promise array
angular.forEach(packages, function(p) {
var promise = vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
var subsystem = response.data.packageManifest.subsystem;
var partNumber = response.data.packageManifest.resultConfig.partNumber;
var packageName = response.data.packageMetaData.packageName;
if(detailedPackages[subsystem] === undefined) {
detailedPackages[subsystem] = {};
}
if(detailedPackages[subsystem][partNumber] === undefined) {
detailedPackages[subsystem][partNumber] = {};
}
detailedPackages[subsystem][partNumber][packageName] = response.data;
});
promises.push(promise);
});
return $q.all(promises).then(function(){
return detailedPackages; // returned data after all promises are done
});
}
这可以使用 promise all 来实现,here。
var promises = [];
promises.push(new Promise(function (resolve, reject) {
vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
...
resolve('If you want to return something')
});
});
//After the loop it's finished you execute your promises
Promise.all(promises).then(function (values) {
... perform more code
});
我正在尝试将结果(数组)从 promise 传递到迭代此结果的函数,为每个项目发出 get 请求并在 returning 之前使用结果创建一个新对象它。问题是在解决承诺并填充它之前,正在 returned 对象。从多个承诺中 return 填充对象的正确方法是什么?
function getPackageDetails(packages) {
var detailedPackages = {};
angular.forEach(packages, function(p) {
vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
var subsystem = response.data.packageManifest.subsystem;
var partNumber = response.data.packageManifest.resultConfig.partNumber;
var packageName = response.data.packageMetaData.packageName;
if(detailedPackages[subsystem] === undefined) {
detailedPackages[subsystem] = {};
}
if(detailedPackages[subsystem][partNumber] === undefined) {
detailedPackages[subsystem][partNumber] = {};
}
detailedPackages[subsystem][partNumber][packageName] = response.data;
});
});
return detailedPackages; // returns before all promises resolved
}
vsmsCampaignFactory.getCampaignPackages(queryString)
.then(function(response) {
vm.packageList = getPackageDetails(response.results);
});
对于这样的情况,您应该考虑使用 $q.all
,在这种情况下,您可以将所有承诺收集在单个承诺数组中,然后将其传递给 $q.all
和 return 结果承诺。它将确保您在完成所有承诺后 returning data
。
在您的代码中,您只是在执行异步 ajax 调用,而不用担心它们是否完成。紧接着您正在 returning detailedPackages
数据。但显然它会是空的。
代码
function getPackageDetails(packages) {
var detailedPackages = {};
var promises = []; //promise array
angular.forEach(packages, function(p) {
var promise = vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
var subsystem = response.data.packageManifest.subsystem;
var partNumber = response.data.packageManifest.resultConfig.partNumber;
var packageName = response.data.packageMetaData.packageName;
if(detailedPackages[subsystem] === undefined) {
detailedPackages[subsystem] = {};
}
if(detailedPackages[subsystem][partNumber] === undefined) {
detailedPackages[subsystem][partNumber] = {};
}
detailedPackages[subsystem][partNumber][packageName] = response.data;
});
promises.push(promise);
});
return $q.all(promises).then(function(){
return detailedPackages; // returned data after all promises are done
});
}
这可以使用 promise all 来实现,here。
var promises = [];
promises.push(new Promise(function (resolve, reject) {
vsmsPackageFactory.getPackage(p.id)
.then(function(response) {
...
resolve('If you want to return something')
});
});
//After the loop it's finished you execute your promises
Promise.all(promises).then(function (values) {
... perform more code
});