下面是我在我的项目中使用的允许用户上传文件的代码。 对于每个选定的文件,“$scope.upload”函数被异步调用。
因为这些是异步调用,所以每次调用都不依赖于之前的调用。
但我的要求是只有在成功回调函数被执行后, 那么下一次上传应该发生,因为每次上传都取决于值 由之前的上传返回。
请告诉我如何实现。 注意:$scope.upload 是部分 Angular 文件上传 js (https://github.com/danialfarid/ng-file-upload)
$scope.startUploading = function ($files, errFiles, item) {
//$files: an array of files selected
for (var idx = 0; idx < $files.length; idx++) {
var $file = $files[idx];
(function (index) {
$scope.upload[index] = $upload.upload({
url: "../UploadCommentAttachment",
method: "POST",
file: $file,
data: item
}).success(function (responseData, status, headers, config) {
item.AuditCommentAttachments.push(responseData);
item.CommentId = responseData.CommentId;
item.AuditId = responseData.AuditId;
item.Operation = "EDIT";
item.CommentAttachmentID = responseData.CommentAttachmentID;
}
});
})(idx);
} ///-- for loop end
} // startuploading end
最佳答案
一般答案
顺序执行异步操作的方法是使用 .then
方法派生的 promise 将它们链接。后续 promise 使用的值应在 .then
方法中返回。
function sequentiallyExecute = function (opList) {
//create initial object
var passedObject = {};
passedObject.dataList = [];
passedObject.response = {};
//create initial promise
var promise = $q.when(passedObject);
//sequentially execute opList
angular.forEach(opList, function(op) {
promise.then(function (passedObject) {
var iPromise = asyncOperation(op, passedObject);
iPromise.then(function onFulfulled(response) {
//save response for chaining
passedObject.response = response;
//push data to list
passedObject.dataList.push(response.data);
//return object for chaining
return passedObject;
});
//return promise for chaining
return iPromise;
});
});
//return promise to client
return promise;
};
在客户端代码中,检索最终数据。
(sequentiallyExecute(opList)
).then (function onFulfilled(passedObject) {
$scope.dataList = passedObject.dataList;
}).catch (function onRejected(error) {
console.error(error);
});
有关链接的更多信息,请参阅 AngularJS $q Service API Reference -- chaining promises .
具体答案
不使用 .success
方法(不可链接),而是使用 .then
方法( 可链接)。
function asychOperation(op, passedObject) {
var $file = op.$file
var item = passedObject.item;
var httpPromise = $upload.upload({
url: "../UploadCommentAttachment",
method: "POST",
file: $file,
data: item
});
var derivedPromise = httpPromise.then(function (response) {
var data = response.data
passedObject.dataList.push(data);
var newItem = {};
newItem.CommentId = data.CommentId;
newItem.AuditId = data.AuditId;
newItem.Operation = "EDIT";
newItem.CommentAttachmentID = data.CommentAttachmentID;
passedObject.item = newItem;
});
var promise = derivedPromise.then (function onFulfilled() {
//return object for chaining
return passedObject;
});
//return promise for chaining
return promise;
};
The
.success
and.error
methods of the$http
service have been removed from the AngularJS framework. Instead use the.then
and.catch
methods.For more information, see
结论
因为调用 promise 的 .then
方法会返回一个新的派生 promise,所以很容易创建一个 promise 链。
可以创建任意长度的链,并且由于一个 promise 可以用另一个 promise 解决(这将进一步延迟其解决),因此可以在链中的任何点暂停/延迟解决 promise。这使得实现强大的 API 成为可能。 1
关于javascript - 循环中的Angularjs异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34959468/