【问题标题】:how do I get this promise back to the controller?我如何将这个承诺返回给控制器?
【发布时间】:2016-12-23 17:03:22
【问题描述】:

所以我在服务中定义了一系列函数,将图像上传到我的 Amazon s3 存储桶,我可以在服务本身中进行 console.log 和警报,一切都会恢复正常。

但是,现在我想将该承诺返回给控制器,以便让用户知道上传已完成。我只是不确定我会怎么做。我曾尝试在 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 来构造它。

【问题讨论】:

    标签: javascript angularjs http promise


    【解决方案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;
        }
    })
    

    【讨论】:

    • 现在我收到这个错误,上面写着“amazonservice.uploadImage(...).then 不是一个函数,当我尝试将 .then 添加到控制器时
    • 想通了,不得不更改最后一行以返回 deferer.promise
    【解决方案2】:

    您应该使用 AngularJs 的 $q 服务来创建延迟对象并返回承诺。 我已经修改了以下代码来演示如何使用 Promise。

    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,您可以在参考中看到它。

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

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

    【讨论】:

      猜你喜欢
      • 2016-07-27
      • 2019-02-05
      • 2015-12-02
      • 2018-04-08
      • 2020-01-23
      • 1970-01-01
      • 2014-01-15
      • 2015-11-27
      • 2015-12-13
      相关资源
      最近更新 更多