javascript - 在图像加载之前不要解决 promise

标签 javascript jquery image base64

假设如下:

  • 循环访问一组 img 标签
  • 获取每个标签的src url
  • 使用 HTML 5 canvas 将其转换为 base64 编码字符串
  • 一旦所有图像都已转换,则应解决 Promise 并调用回调

我的问题:

  • 我需要等待每个图像加载到 canvas 中,然后才能将其转换为 base64
  • 为了解决这个问题,我使用了 `img.onload = function(){ ..... return base64Img; };
  • 不幸的是,每次调用 img.src = element.src; 都会解决 promise ,它不会等待图像加载并调用 return base64Img;因此,当调用 $.when.apply($, Promise).then(function(){}); 时,我最终得到一个空数组。

如何更改此 promise ,以便在加载和转换所有图像之前它不会解析?

 function accountCreation(){
    $('#container').hide(); // hide the display while we save the info as it will take a few seconds, you should do a loading bar or something here instead
    var user = Parse.User.current(); // get the currently logged in user object

    // loop through each image element
    var promises = $('.images').map(function(index, element) {
          var src = $(element).attr('src');
          var canvas = document.createElement('CANVAS');
          var ctx = canvas.getContext('2d');
          var img = new Image;
          img.crossOrigin = 'Anonymous';
          img.onload = function(){
              canvas.height = img.height;
              canvas.width = img.width;
              ctx.drawImage(img,0,0);
              var base64Img = canvas.toDataURL('image/png');
              // Clean up
              canvas = null; 
              return base64Img;
          };
          img.src = element.src;
    });
    $.when.apply($, promises).then(function() {
        // arguments[0][0] is first result
        // arguments[1][0] is second result and so on
        for (var i = 0; i < arguments.length; i++) {
            var file = new Parse.File("photo.jpg", { base64: arguments[i]}); // this part actually saves the image file to parse
            user.set("image" + i, file); // set this image to the corosponding column on our object 
        }
        // save the user object
        user.save(null,{
          success: function(user) { 
                  $('#message').html('Profile Updated!');
                  $('#container').show(); // show the screen again, you should just remove your loading bar now if you used one
          },
          error: function(user, error) {
                  console.log('Failed to create new object, with error code: ' + error.message);
          }
        });
    });
 }

最佳答案

您的 promise 数组仅包含未定义的值,因为回调函数不返回任何内容。由于数组中没有 Deferred 对象,因此 when 方法无需等待任何内容,因此它会正确运行 then 回调离开。

创建一个要返回的Deferred对象,并在加载图像时解析它:

var promises = $('.images').map(function(index, element) {
    // created a Deferred object to return
    var deferred = $.Deferred();
    var src = $(element).attr('src');
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var img = new Image;
    img.crossOrigin = 'Anonymous';
    img.onload = function(){
        canvas.height = img.height;
        canvas.width = img.width;
        ctx.drawImage(img,0,0);
        var base64Img = canvas.toDataURL('image/png');
        // Clean up
        canvas = null;
        // Resolve the Deferred object when image is ready
        deferred.resolve(base64Img);
    };
    img.src = element.src;
    // return the Deferred object so that it ends up in the array
    return deferred;
});

关于javascript - 在图像加载之前不要解决 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28909557/

相关文章:

javascript - 每 10 秒刷新一次 div 复制 div

javascript - 如何使用 queryselector 验证两个输入字段是否已填写?

javascript - jquery fancybox2 - 使用 fancybox 加载 div

javascript - jQuery 代码在 FF、Chrome 中工作,但在 IE 中不工作

javascript - jQuery 在 keyup 上使用类获取输入 ID 不起作用

javascript - 在异步函数更新 Node.js 模块后,如何从该模块返回值?

javascript - 如何突出显示下拉菜单中的选项?

jquery - 即使图像不存在,也会触发图像加载回调

JavaScript 更改图像源不持久

html - 使用 Bootstrap 的 Grid img 响应问题