使用承诺和邮袋调整图片大小

时间:2017-03-29 21:04:36

标签: javascript jquery image promise pouchdb

之前我问过这个并尝试根据一些答案进行更改,但仍然存在承诺问题。

这实际上是多个承诺,但主要问题是我正在调用pouch.get来获取图像列表。然后我通过for / loop来创建一些标记(如果我没有resize promise代码,它可以正常工作)。我正在尝试创建一组缩略图,以便在网格中的手机上显示。

我使调整大小代码成为一个承诺,尝试在完成调整之前完成调整大小,然后再调整另一个图像。但它最终只为最后一张图片做了一次onload事件,而这就是所有显示的内容。

发生的事情是每个循环进入resize,设置onload事件,将url复制到图像然后跳出并执行下一个循环并且onload事件在最后一个循环之前不会被触发(图像),显示在屏幕上。

我的调整承诺:

function resizeImageToImgPromise(showImage, maxWidth, maxHeight, url) {
   // Set img src to ObjectURL

   return new Promise(function (resolve, reject) {
      var test;
      test = 'test';
      showImage.onload = function () {
     URL.revokeObjectURL(this.src);
     var canvas = document.createElement("canvas");
     var ctx = canvas.getContext("2d");


   ... removed code to make it easier to read and not germane to the issue

     showImage.src = canvas.toDataURL("image/png");
     showImage.width = width;
     showImage.height;
     showImage.style.display = "inline";
     showImage.style.margin = "10px"

     resolve();
      }

      showImage.src = url;
   })
}

这是在for循环中调用它的承诺:

function readAllImagesFromPouch(id, imageDisplay) {

   return new Promise(function (resolve, reject) {

      var startElement = document.getElementById(imageDisplay);
      var image = "";
      var imgBlob;
      var base64str;

      // Get all attachments for this id

      DB_TaskImages.get(id, { attachments: true }).then(function (doc) {

     for (var key in doc._attachments) {
        var img = document.createElement('img');
        base64str = doc._attachments[key].data;
        blobUtil.base64StringToBlob(base64str).then(function (myBlob) {
           console.log();
           return blobUtil.createObjectURL(myBlob);
        }).then(function (myUrl) {

           img.src = myUrl;

           resizeImageToImgPromise(img, "100", "60", myUrl).then(function () {

          $(startElement).append(img.outerHTML);                              return;
           }).catch(function () {    // this is the catch for the resize
          alert("this is an error");
           })
        }).catch(function (err) {   // this is the catch for the blobUtil
           // error
        });
     }
     return;
      }).then(function () {
     resolve();
      }).catch(function (err) {      // this is the catch for the DB_TaskImages.get
     reject(err);
      })
   });         // end of promise
}

这最初来自:

    readAllImagesFromPouch("006", "divImages").then(function () {
    }).catch(function (err) {
       console.log("In catch for readAllImagesFromPouch with err: " + err);
    })

1 个答案:

答案 0 :(得分:0)

首先,避免使用promise构造函数反模式。当DB_TaskImages.get返回一个promise时,您不需要将代码包装在一个

其次,你的for...in循环启动了一堆异步任务 - 但你实际上并没有等待它们完成

此代码将遍历doc._attachments并执行“并行”中的resize - 只有在所有调整大小完成后才会显示已调整大小的图片

function readAllImagesFromPouch(id, imageDisplay) {
    var startElement = document.getElementById(imageDisplay);
    return DB_TaskImages.get(id, {
        attachments: true
    }).then(function(doc) {
        return Promise.all(Object.keys(doc._attachments)
            .map(function(key) {
                var base64str = doc._attachments[key].data;
                return blobUtil.base64StringToBlob(base64str)
                .then(blobUtil.createObjectURL)
                .then(function(myUrl) {
                    return resizeImageToImgPromise("100", "60", myUrl);
                });
            })
        );
    }).then(function(images) {
        images.forEach(function(img) {
            $(startElement).append(img.outerHTML);
        });
    });
}

注意:没有完成错误处理,因此任何点上的任何错误都将导致不显示图像