我之前问过这个问题,并试图根据一些答案进行更改,但仍然对承诺有问题。
这实际上是多个承诺,但主要问题是我调用pouch.get以获取图像列表。 然后,我通过一个for/循环来创建一些标记(如果我没有调整大小的承诺代码,则可以正常工作)。 我正在尝试创建一堆缩略图图像以网格的形式显示在手机上。
我使调整大小代码承诺在继续并获取另一个图像以调整大小之前尝试完成调整大小。 但它最终只对最后一个图像执行一个 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);
})
首先,避免 promise 构造函数反模式。由于DB_TaskImages.get
返回一个承诺,因此您无需将代码包装在一个代码中
其次,你的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);
});
});
}
注意:没有进行错误处理,因此任何时候的任何错误都会导致不显示任何图像