转换为base64 AngularJS时获得异步功能

时间:2015-12-08 10:56:16

标签: javascript angularjs

我是移动开发者,目前正在使用angularJS和ionic开发混合移动应用。

现在我遇到了异步函数问题,它必须在完成所有转换和映射后返回值,但现在我总是得到null值,因为转换运行时它比映射花费的时间稍长,

我想在转换完成后运行我的映射。

这是我的服务

angular.module('file.service', ['ionic'])
.factory('fileService', [‘$q’, function($q) {
    var factory = {};

    factory.getContentImageFix = function(fileParsing){
        var contentImg = [];
        for(var i = 0; i < fileParsing.length; i++){
            convertFileToDataURLviaFileReader(fileParsing[i].fullpath, function(base64Img){
                contentImg.push({
                    image: base64Img,
                    width: 400
                });
            });
        }
        return $q.all(contentImg);
    }

    function convertFileToDataURLviaFileReader(url, callback){
        var xhr = new XMLHttpRequest();
        xhr.responseType = 'blob';
        xhr.onload = function() {
            var reader  = new FileReader();
            reader.onloadend = function () {
                callback(reader.result);
            }
            reader.readAsDataURL(xhr.response);
        };
        xhr.open('GET', url);
        xhr.send();
    }
}]);

和我的控制器一样

angular.module('scan.module’, ['ionic'])
.controller('scanController’, [‘fileService’, function(fileService) {
    var fileParsing = [
        {
            “name”:”a.jpg",
            "fullpath”:”[PATH]/a.jpg"
        },{
            "name”:”b.jpg",
            "fullpath":"[PATH]/b.jpg"
        }
    ];
    var contentImg = fileService.getContentImageFix(fileParsing);
    console.log(JSON.stringify(contentImg)); //not it is return zero array
}]);

实际上我并不真正了解承诺的概念,所以如何解决这个异步问题。

谢谢,

2 个答案:

答案 0 :(得分:1)

$ q.all()接受promises数组,因此你可以改变convertFileToDataURLviaFileReader函数来返回promise,就像这样

function convertFileToDataURLviaFileReader(url){
    var defer = $q.defer();
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function() {
        var reader  = new FileReader();
        reader.onloadend = function () {
            defer.resolve(reader.result);
        }
        reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.send();
    return defer.promise;
}

然后

factory.getContentImageFix = function(fileParsing){
    var contentImg = [];
    for(var i = 0; i < fileParsing.length; i++){
          contentImg.push(convertFileToDataURLviaFileReader(fileParsing[i].fullpath));
    }
    return $q.all(contentImg);
}

并在控制器中

fileService.getContentImageFix(fileParsing).then(function(contentImg){
    console.log(JSON.stringify(contentImg))
})

答案 1 :(得分:0)

因为看起来接受的答案并不奏效:

http://plnkr.co/edit/SXKNbBc2b32UTzYIVsrB?p=preview

  FileService.getContentImages(files).then(function(images) {
    $timeout(function() {
      mv.images = images;

      console.log(images);
    }, 0);
  });

将异步数据导入当前的$ digest时出现问题。这是通过简单的超时解决的。

我做的其他更改是引入一个指令使其工作,因为指令优于div中的controllerAs:)