$q.all is resolving before the returns

2019-02-25 00:56发布

问题:

The $q.all is resolving before either of its functions has resolved.

I'm uploading two files to azure blob storage using $.ajax (I couldn't get $http to work):

 function doPhotos (result, i)
    {
        var d = $q.defer();
        var requestData = new Uint8Array($scope.files[i].postArray);
        $.ajax({
            url: result.photos[i].imageUri,
            type: "PUT",
            data: requestData,
            processData: false,
            beforeSend: function (xhr)
            {
                xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
                xhr.setRequestHeader('x-ms-blob-content-type', $scope.files[i].type);
                xhr.setRequestHeader('x-ms-meta-uploadvia', 'CORS Demo');
                xhr.setRequestHeader('Content-Length', requestData.length);
            },
            success: function (data, status)
            {
                d.resolve(data);

            },
            error: function (xhr, desc, err)
            {
                console.log('error uploading photo ' + desc);
                d.resolve(err);


            }
        });
        return d.promise;

    }

This is the function that sets up the $q.all and is being called on a ng-click:

$scope.createVotation = function () {
        services.photoset.create($scope.model).then(function (result) {
            $scope.model.id = result.id;
            var doPhotosArray= [];
            for (var i in result.photos) {
                doPhotosArray[i] = doPhotos(result, i);    
            }

            $q.all(doPhotosArray).then(function (data)
            {
                // this is being called almost immediately before the photos upload
                $scope.safeApply(function ()
                {
                    $scope.submitting = false;
                    $location.path('/vote/update/' + $scope.model.id);

                });
            });

        });
    }
};

html:

<button ng-click='createVotation()'>Create</button>

The q.all->then is being called before even the first doPhoto resolve is called. I'm not sure if there is some issue with using jQuery's ajax but it is my understanding that $q.all should wait until both promises (in my case there are 2) are fulfilled before entering its then.

As an added twist, the photos are being uploaded so that is working, it is the $q.all that is not waiting.

回答1:

After doing some research and thinking about the various comments from @charlietfl, the only way I could get the $q.all to work properly is do assign the function call to a variable and then push it into the array that is being passed to q.all.

for (var i in result.photos)
{
    var output = doPhotos(result, i);
    doPhotosArray.push(output);
} 

The various examples that I used for reference seem to indicate that the code in my original question should work but doesn't.