异步循环函数中的角度承诺

时间:2014-02-20 09:26:18

标签: angularjs

我有一个上传功能,它循环选定的文件并将它们添加到服务器文件系统上。

上传工厂

app.factory('uploadFactory', function ($upload, $q) {

    var uploadFactory = {};

    var image = {
        Models: [],
        Images: [],
        uploadImages: function () {
            var defer = $q.defer();
            for (var i = 0; i < this.Models.length; i++) {
                var $file = this.Models[i].file;
                (function (index) {
                    $upload
                        .upload({
                            url: "/api/upload/",
                            method: "POST",
                            file: $file
                        })
                        .success(function (data, result) {
                            // Add returned file data to model
                            var imageObject = {
                                Path: data.Path,
                                Description: image.Models[index].Description,
                                Photographer: image.Models[index].Photographer
                            };
                            image.Images.push(imageObject);

                            defer.resolve(result);
                        });
                })(i);
            }
            return defer.promise;
        }
    };

    uploadFactory.image = function () {
        return image;
    };

    return uploadFactory;
});

在我的控制器中

$scope.imageUpload = new uploadFactory.image;
$scope.create = function () {
    var uploadImages = $scope.imageUpload.uploadImages();
    uploadImages.then(function () 
        $scope.ship.Images = $scope.imageUpload.Images;
        shipFactory.create($scope.ship).success(successPostCallback).error(errorCallback);
    });
};

我的问题是,承诺只承担通过循环进行首次上传的承诺。我已经阅读了有关$q.all()的内容,但我不确定如何实现它。

如何让它贯穿整个循环?谢谢!

解决方案

var image = {
    Models: [],
    Images: [],
    uploadImages: function () {
        for (var i = 0; i < this.Models.length; i++) {
            var $file = this.Models[i].file;
            var defer = $q.defer();

            (function (index) {
                var promise = $upload
                    .upload({
                        url: "/api/upload/",
                        method: "POST",
                        file: $file
                    })
                    .success(function (data, result) {
                        // Add returned file data to model
                        var imageObject = {
                            Path: data.Path,
                            Description: image.Models[index].Description,
                            Photographer: image.Models[index].Photographer
                        };
                        image.Images.push(imageObject);

                        defer.resolve(result);
                    });
                promises.push(promise);
            })(i);
        }
        return $q.all(promises);
    }
};

1 个答案:

答案 0 :(得分:4)

你是对的$q.all()是去这里的方式(完全未经测试 - 但我认为这至少是正确的方向......):

app.factory('uploadFactory', function ($upload, $q) {

    var uploadFactory = {};

    var image = {
        Models: [],
        Images: [],
        uploadImages: function () {

            var promises = [];

            for (var i = 0; i < this.Models.length; i++) {

                var $file = this.Models[i].file;
                var response = $upload
                    .upload({
                        url: "/api/upload/",
                        method: "POST",
                        file: $file
                    })
                    .success(function (data, result) {
                        // Add returned file data to model
                        var imageObject = {
                            Path: data.Path,
                            Description: $file.Description,
                            Photographer: $file.Photographer
                        };
                        image.Images.push(imageObject);
                    });

                promises.push(response);
            }
            return $q.all(promises);
        }
    };

    uploadFactory.image = function () {
        return image;
    };

    return uploadFactory;
});