Javascript 使用promise和Pocket调整图像大小

Javascript 使用promise和Pocket调整图像大小,javascript,jquery,image,promise,pouchdb,Javascript,Jquery,Image,Promise,Pouchdb,我以前问过这个问题,并试图根据一些答案来改变它,但仍然对承诺有疑问 这实际上是多个承诺,但主要的问题是我正在打电话给palk.get获取图像列表。然后,我通过一个for/循环创建一些标记(如果没有resizepromise代码,这很好)。我正在尝试创建一组缩略图图像,以网格形式显示在手机上 我做了一个调整大小的代码的承诺,尝试并得到调整完成之前,去和得到另一个图像的大小。但它最终只为最后一张图像执行一个onload事件,这就是所有显示的内容 发生的情况是,对于每个循环,它进入调整大小,设置onl

我以前问过这个问题,并试图根据一些答案来改变它,但仍然对承诺有疑问

这实际上是多个承诺,但主要的问题是我正在打电话给palk.get获取图像列表。然后,我通过一个for/循环创建一些标记(如果没有resizepromise代码,这很好)。我正在尝试创建一组缩略图图像,以网格形式显示在手机上

我做了一个调整大小的代码的承诺,尝试并得到调整完成之前,去和得到另一个图像的大小。但它最终只为最后一张图像执行一个onload事件,这就是所有显示的内容

发生的情况是,对于每个循环,它进入调整大小,设置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);
    })

首先,避免承诺构造函数反模式。由于
DB\u TaskImages.get
返回一个承诺,您不需要将代码封装在一个承诺中

其次,您的for…in循环启动了一系列异步任务,但实际上您并不等待它们完成

此代码将在
文档中循环。_附件
并“并行”执行
调整大小
——只有所有调整大小完成后,才会显示调整大小的图像

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

注意:未进行错误处理,因此任何点上的任何错误都将导致不显示任何图像

我认为我以前的回答毫无帮助?-也许您可以告诉我该代码有什么问题-我假设我的代码不起作用,因为您在这个问题中的代码仍然使用Promise构造函数反模式,并且盲目地循环通过
doc.\u附件进行异步调用您的代码的主要问题是
var img=document.createElement('img')在一个循环中分配给每个
文档。_附件
-异步代码直到
for…in
循环结束时才开始-因此,
img
对于所有异步代码也是最后一个,
这是调整大小的陷阱
-您的
调整大小
永远不会拒绝,因为错误的唯一来源将在
showImage.onload
回调中,并且这些不会成为“拒绝”-当然,如果
removed
代码包含一个
reject
调用,那么您可以忽略它comment@JaromandaX当前位置有点让人困惑。我不确定反模式是什么。现在我知道了,您所说的异步代码直到循环结束才开始是正确的。它实际上在for循环之后执行所有三行,然后执行blol的“then”,但循环数相同,然后执行resize部分,但直到最后才执行onload,然后出于某种原因将无限地执行它们。如果我注释掉调整大小的承诺,它将显示我想要的所有图像(除非它们不会调整大小)。我真的不知道该如何解决这个问题。@JaromandaX:我在另一篇文章中没有看到我的代码被重写。我会看看它,看看它是否解决了我的问题。谢谢。我添加了调整大小功能,以查看承诺是否会导致失败。请不要用您的代码编辑答案-如果您有答案,您可以发布答案,或者用更新的代码编辑您的问题。我刚刚了解了这里发生的事。在onload部分中,它将更改的图像移动到onload所在的同一图像中。所以我猜它一直在运行,我只需要将showImage.src设为空,使它正常工作。它现在可以正常工作了。我只需要更仔细地看看你做了什么来理解它。谢谢。