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;


}

最佳答案

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()已经返回承诺,则只需返回该承诺。如果不是,则可以在uploadFile()的开头创建一个,然后在末尾将其返回,然后在.success().error()处理程序中对其进行解析或拒绝。



如果fileService.uploadDocument()已经可以做出承诺,那么首选解决方案就是使用该承诺(我不知道该API,所以也不知道它是如何工作的)。如果无法兑现承诺,那么您可以像这样做出自己的承诺:

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;
}

10-05 21:57