如何将此承诺发回控制器?

时间:2016-08-17 06:46:34

标签: javascript angularjs http promise

所以我在服务中定义了一系列功能,将图像上传到我的Amazon s3存储桶,我可以在服务本身中控制日志并提醒,一切都恢复正常。

但是,现在我想将该承诺返回给控制器,这样我就可以让用户知道上传完成了。我只是不确定我会怎么做。我已经尝试在filereader.onload上放回车,但后来我发现错误说我所回复的不是承诺等等。这是我的代码:

angular.module("testApp", [])
.controller("testCtrl", function($scope, amazonService) {
    $scope.test = "leeroy jenkins";

    $scope.upload = function() {
        amazonService.uploadImage($('#file'));
    }
})
.service("amazonService", function($http) {
    var url = "/api/"
    var uploadImageFilestream = function(obj) {
        return $http({
            method: "PUT",
            url: url + "media/images",
            data: obj
        }).then(function(res) {
            if (res.status === 200) {
                alert("upload successful!");
            }
            return res;
        });
    }

    var formatFileName = function(filename, newBase) {
        //first, get the file extension
        var extension = filename.substring(filename.lastIndexOf("."));
        return newBase + extension;
    }

    this.uploadImage = function(obj) {
        var file = obj[0].files[0];
        var fileReader = new FileReader();

        fileReader.onload = function(loaded) {
            uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result});
        }

        fileReader.readAsDataURL(file);
    }
})

我知道如果我将uploadImageFilestream函数与uploadImage函数结合起来就可以了,但是我不知道如何在单独的函数中使用promise来构造它。

2 个答案:

答案 0 :(得分:1)

使用$q

.service("amazonService", function($http, $q) {
    var url = "/api/"
    var uploadImageFilestream = function(obj) {
        return $http({
            method: "PUT",
            url: url + "media/images",
            data: obj
        });
    }

    var formatFileName = function(filename, newBase) {
        //first, get the file extension
        var extension = filename.substring(filename.lastIndexOf("."));
        return newBase + extension;
    }

    this.uploadImage = function(obj) {
        var file = obj[0].files[0];
        var fileReader = new FileReader();

        var deferer = $q.defer();

        fileReader.onload = function(loaded) {
            uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result})
            .then(function(res) {
                if (res.status === 200) {
                    deferer.resolve();
                    alert("upload successful!");
                }
                return res;
            });
        }

        fileReader.readAsDataURL(file);

        return deferer.promise;
    }
})

答案 1 :(得分:0)

您应该使用AngularJs的$ q服务来创建延迟对象并返回promise。 我修改了以下代码以演示使用promises的方法。

angular.module("testApp", [])
.controller("testCtrl", function($scope, amazonService) {
    $scope.test = "leeroy jenkins";

    $scope.upload = function() {
        var promise = amazonService.uploadImage($('#file')); // call to function returns promise 
        promise.then(function(){ // when promise is resolved, desired data is passed
            alert("success");
        }).catch(function(error){ // when promise is rejected, related error object is passed
            alert("failure");
        });
    }
})
.service("amazonService", function($http, $q) { // added $q service to handle promises
    var url = "/api/"
    var uploadImageFilestream = function(obj) {
        return $http({
            method: "PUT",
            url: url + "media/images",
            data: obj
        }).then(function(res) {
            if (res.status === 200) {
                alert("upload successful!");
            }
            return res;
        });
    }

    var formatFileName = function(filename, newBase) {
        //first, get the file extension
        var extension = filename.substring(filename.lastIndexOf("."));
        return newBase + extension;
    }

    this.uploadImage = function(obj) {
        var file = obj[0].files[0];
        var fileReader = new FileReader();
        var deferredObject = $q.defer(); // added deferred object which will be used to return promise and resolve or reject is as shown below
        fileReader.onload = function(loaded) {
            uploadImageFilestream({fileName: formatFileName(file.name, "test1"), fileBody: loaded.target.result}).then(response){
                deferredObject.resolve(response); // when resolve function of deferred object is called success callback in controller will be called with the data you pass here
            }).catch(function(errorObj){
                deferredObject.reject(errorObj); // when reject function of deferred object is called error callback is controller will be called with the error object you pass here
            });
        }

        fileReader.readAsDataURL(file);
        return deferredObject.promise; // return promise object which will be resolve or reject and accordingly success callback and error callback will be called with then and catch respectively
    }
});

链接到AngularJs Reference。 还有其他不同的方法来创建和返回承诺,您可以在参考中看到它。

另一种创建和返回promise的方法是使用$ q object作为函数并直接传递回调,如下所示:

// for the purpose of this example let's assume that variables `$q` and `okToGreet`
// are available in the current lexical scope (they could have been injected or passed in).
// for the purpose of this example let's assume that variables `$q` and `okToGreet`
// are available in the current lexical scope (they could have been injected or passed in).

function asyncGreet(name) {
  // perform some asynchronous operation, resolve or reject the promise when appropriate.
  return $q(function(resolve, reject) {
    setTimeout(function() {
      if (okToGreet(name)) {
        resolve('Hello, ' + name + '!');
      } else {
        reject('Greeting ' + name + ' is not allowed.');
      }
    }, 1000);
  });
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
});