javascript - 循环中的Angularjs异步调用

标签 javascript angularjs asynchronous

下面是我在我的项目中使用的允许用户上传文件的代码。 对于每个选定的文件,“$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/

相关文章:

javascript - 如何在 document.ready 中访问我的表单值

JavaScript fancybox "conflict wrapper"代码,它是如何工作的?

javascript - 使用扩展运算符组合未知数量的对象

javascript - 制作交互式 Angular 谷歌图表指令来集成气泡图

asp.net-mvc - 不正确的 http header 字段值编码

java - 我怎样才能使这个线程安全?

javascript - 在 vuetify 中关闭芯片时如何停止选择打开?

javascript - node busboy + express 4 + ng-file-upload 不触发事件

javascript - 了解node.js中的请求获取

C# WebClient 使用异步并返回数据