承诺在循环中不能正常工作

时间:2014-08-11 10:03:35

标签: javascript angularjs promise angular-promise

Promise无法正常工作 saveService 在承诺解决之前被调用意味着所有文档都已上传,但当我在 saveService 中记录数据时,它显示上传的文档无法弄明白这个问题,请让我知道我哪里错了

//file upload
$scope.fileObj = {};
$scope.documentUploaded = [];
var uploadFile = function (type) {

    var file = $scope.fileObj[type];

    //service to upload file
    fileService.uploadDocument(file)
        .success(function (data, status) {

            console.log("uploaded successfully", data);

            $scope.documentUploaded.push({
                doc: {
                    fileName: data.name,
                    path: data.path
                }
            });

        })
        .error(function (data, status) {

        });          
}


$scope.save = function () { //on click of submit, save() is called

var defer = $q.defer();
var promises = [];        

//looping to upload files       
angular.forEach($scope.documentList, function (doc) {

    if ($scope.fileObj[doc.type]) {
       promises.push(uploadFile(doc.type));                
    }            
});

//this will save data when promise will get complete
var saveData = function () {
    var dataToSave = {
        //other fields
        documents: $scope.documentUploaded
    };

    saveService.saveApi(dataToSave)
        .success(function () {
            defer.resolve('data saved');                    
        })
        .error(function () {
            defer.reject("something went wrong");                    
        });
}

$q.all(promises).then(saveData);
return defer;         

}

1 个答案:

答案 0 :(得分:3)

uploadFile()需要返回一个承诺(在完成其工作时已解决)$q.all(promises)才能生效。

现在它不会返回任何内容,因此您传递$q.all()一组未定义的值。由于该数组中没有promise,$q.all()会立即执行.then()处理程序。

这是问题的简要版本:

var promises = [];
...forEach(function() {
    promises.push(uploadFile(doc.type)); 
});
$q.all(promises).then(saveData);

因此,您将uploadFile()的返回值推入promises数组。但uploadFile()甚至没有任何回报。所以,你正在推进undefined。然后,当undefined期望一系列承诺时,您将$q.all值数组传递给uploadFile()

因此,为了使这个逻辑工作,你需要uploadfile()来返回一个在fileService.uploadDocument()的实例完成异步工作时得到解决的promise。


如果uploadFile()已经返回承诺,您可以返回该承诺。如果没有,那么您可以在.success()的开头创建一个并在结尾处返回,然后在.error()fileService.uploadDocument()处理程序中解析或拒绝它。


如果var uploadFile = function (type) { var defer = $q.defer(); var file = $scope.fileObj[type]; //service to upload file fileService.uploadDocument(file) .success(function (data, status) { console.log("uploaded successfully", data); $scope.documentUploaded.push({ doc: { fileName: data.name, path: data.path } }); defer.resolve(); }) .error(function (data, status) { defer.reject(); }); return defer.promise; } 已经可以做出承诺,那么首选解决方案就是使用该承诺(我不知道API因此不知道它是如何工作的)。如果它不能做出承诺,那么你就可以这样做:

{{1}}