AngularJS 中的多个异步调用使用结果
Multiple asynchronous calls in AngularJS using the result
在我正在开发的 AngularJS 应用程序中,我试图异步处理多个上传的文件,以便为将它们添加到 SuiteCRM 实例的例程做好准备。总的来说,代码没有错误,但我发现延迟调用一个接一个地执行,并且在所有承诺都得到解决之前不会将结果传递给等待脚本。也许有人可以帮助我了解如何链接这些以获得我想要的结果?
function fileReader(file) { // perform async operation
var deferred = $q.defer();
var reader = new FileReader();
reader.onload = function () {
deferred.resolve(reader.result.replace(/^(.*),/g, ""));
};
reader.readAsDataURL(file);
return deferred.promise;
}
$scope.uploadFiles = function () {
console.log('Starting uploads');
$scope.uploadClicked = true;
$scope.uploadProgress = {};
$applicationID = $('#application_id').val();
var tmpMerchData = SessionService.getMerchantData();
var isoID = SessionService.getISOID();
if ($scope.fileList && $scope.fileList.length) {
var $myFiles = $scope.fileList;
for (var f = 0; f < $myFiles.length; f++) {
var thisFile = $myFiles[f];
console.debug(thisFile);
fileReader(thisFile.file).then(function (result) {
ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, result, thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID).then(
function successCallback(response) {
if (response.data.status === 1) {
console.log("Document creation succeeded");
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log("Document creation failed");
}
}, function errorCallback(response) {
console.debug("Error returned from createNewUploadedDocument", response);
});
});
}
}
};
所以,你看,我需要 FileReader 来处理文件,return 文件的内容,以便将它传递给 $[= 中每个 f(文件)的 createNewUploadedDocument 函数23=]。 NGF 的多个文件选项对我不可用,因为每个文件都有特定的模板类型和描述。
如果您能提供或建议任何帮助,我们将不胜感激。
EDIT - 我已阅读这篇文章 and this angular $q, How to chain multiple promises within and after a for-loop,但都没有针对我的具体情况提供任何有用的反馈。我知道 promises 可以使用 $q.all 嵌套和组合,但它们仍然可以相互提供结果数据吗?
我的内部方法是调用 REST API - 没有任何区别 - 但我确实需要 FileReader 承诺的结果才能调用它。
您可以有效地使用$q 服务。
当你使用 $q.all() 时,你传递了一个承诺数组,结果你得到了一个以相同顺序排列的每个承诺的结果数组。
所以我们可以像这样重写你的代码:
if ($scope.fileList && $scope.fileList.length) {
var $myFiles = $scope.fileList;
var promisesFileReader = [];
var promisesUploadedDocument = [];
for (var f = 0; f < $myFiles.length; f++) {
var thisFile = $myFiles[f];
console.debug(thisFile);
promisesFileReader.push(fileReader(thisFile.file));
}
$q.all(promisesFileReader)
.then(function(results) {
//We loop on results and push all the UploadDocument promises with the correct result
for (var i = 0; i < results.length; i++) {
promisesUploadedDocument.push(ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, results[i], thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID));
}
$q.all(promisesUploadedDocument)
.then(
function successCallback(response) {
if (response.data.status === 1) {
console.log("Document creation succeeded");
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log("Document creation failed");
}
},
function errorCallback(response) {
console.debug("Error returned from createNewUploadedDocument", response);
});
});
}
答案 - 这个原始代码的更新版本解决了这个问题。
请注意,angular.forEach
已实现以及一些清理变量名称和重用。
$scope.uploadFiles = function () {
console.log('Starting uploads');
$scope.uploadClicked = true;
$scope.uploadProgress = {};
$applicationID = $('#application_id').val();
var tmpMerchData = SessionService.getMerchantData();
var isoID = SessionService.getISOID();
if ($scope.fileList && $scope.fileList.length) {
angular.forEach($scope.fileList, function (thisFile, f) {
console.log('Starting upload #', f);
fileReader(thisFile.file).then(
function (fileContents) {
ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, fileContents, thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID).then(
function successCallBack(response) {
if (response.data.status === 1) {
console.log('Document creation succeeded');
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log('Document creation failed');
}
}, function errorCallback(response) {
console.debug('Error returned from createNewUploadedDocument ', response);
});
});
});
}
};
在我正在开发的 AngularJS 应用程序中,我试图异步处理多个上传的文件,以便为将它们添加到 SuiteCRM 实例的例程做好准备。总的来说,代码没有错误,但我发现延迟调用一个接一个地执行,并且在所有承诺都得到解决之前不会将结果传递给等待脚本。也许有人可以帮助我了解如何链接这些以获得我想要的结果?
function fileReader(file) { // perform async operation
var deferred = $q.defer();
var reader = new FileReader();
reader.onload = function () {
deferred.resolve(reader.result.replace(/^(.*),/g, ""));
};
reader.readAsDataURL(file);
return deferred.promise;
}
$scope.uploadFiles = function () {
console.log('Starting uploads');
$scope.uploadClicked = true;
$scope.uploadProgress = {};
$applicationID = $('#application_id').val();
var tmpMerchData = SessionService.getMerchantData();
var isoID = SessionService.getISOID();
if ($scope.fileList && $scope.fileList.length) {
var $myFiles = $scope.fileList;
for (var f = 0; f < $myFiles.length; f++) {
var thisFile = $myFiles[f];
console.debug(thisFile);
fileReader(thisFile.file).then(function (result) {
ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, result, thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID).then(
function successCallback(response) {
if (response.data.status === 1) {
console.log("Document creation succeeded");
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log("Document creation failed");
}
}, function errorCallback(response) {
console.debug("Error returned from createNewUploadedDocument", response);
});
});
}
}
};
所以,你看,我需要 FileReader 来处理文件,return 文件的内容,以便将它传递给 $[= 中每个 f(文件)的 createNewUploadedDocument 函数23=]。 NGF 的多个文件选项对我不可用,因为每个文件都有特定的模板类型和描述。
如果您能提供或建议任何帮助,我们将不胜感激。
EDIT - 我已阅读这篇文章
您可以有效地使用$q 服务。 当你使用 $q.all() 时,你传递了一个承诺数组,结果你得到了一个以相同顺序排列的每个承诺的结果数组。 所以我们可以像这样重写你的代码:
if ($scope.fileList && $scope.fileList.length) {
var $myFiles = $scope.fileList;
var promisesFileReader = [];
var promisesUploadedDocument = [];
for (var f = 0; f < $myFiles.length; f++) {
var thisFile = $myFiles[f];
console.debug(thisFile);
promisesFileReader.push(fileReader(thisFile.file));
}
$q.all(promisesFileReader)
.then(function(results) {
//We loop on results and push all the UploadDocument promises with the correct result
for (var i = 0; i < results.length; i++) {
promisesUploadedDocument.push(ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, results[i], thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID));
}
$q.all(promisesUploadedDocument)
.then(
function successCallback(response) {
if (response.data.status === 1) {
console.log("Document creation succeeded");
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log("Document creation failed");
}
},
function errorCallback(response) {
console.debug("Error returned from createNewUploadedDocument", response);
});
});
}
答案 - 这个原始代码的更新版本解决了这个问题。
请注意,angular.forEach
已实现以及一些清理变量名称和重用。
$scope.uploadFiles = function () {
console.log('Starting uploads');
$scope.uploadClicked = true;
$scope.uploadProgress = {};
$applicationID = $('#application_id').val();
var tmpMerchData = SessionService.getMerchantData();
var isoID = SessionService.getISOID();
if ($scope.fileList && $scope.fileList.length) {
angular.forEach($scope.fileList, function (thisFile, f) {
console.log('Starting upload #', f);
fileReader(thisFile.file).then(
function (fileContents) {
ApplicationFactory.createNewUploadedDocument(thisFile, thisFile.templatetype, fileContents, thisFile.description, $scope.userID, tmpMerchData.id, $applicationID, isoID).then(
function successCallBack(response) {
if (response.data.status === 1) {
console.log('Document creation succeeded');
$scope.uploadProgress = {
'progress': 100,
'index': f
};
} else {
console.log('Document creation failed');
}
}, function errorCallback(response) {
console.debug('Error returned from createNewUploadedDocument ', response);
});
});
});
}
};