我承诺以前似乎有效,但现在没有。
我认为我已经完成了所有工作,但是在调用.get之后,它永远不会进入for循环。
它跳到最后并超出承诺,然后返回到返回(在.get内)然后到决心然后退出。
如果有错误,它应该跳转到catch但是没有,那么它是如何错过for循环的?
以下是代码:
function readAllImagesFromPouch(id, imageDisplay) {
return new Promise(function (resolve, reject) {
var startElement = document.getElementById(imageDisplay);
var image = "";
// Get all attachments for this id
DB_TaskImages.get(id, { attachments: true }).then(function (doc) {
for (var key in doc._attachments) {
DB_TaskImages.getAttachment(doc._id, key).then(function (blob) {
var img = document.createElement('img');
blob = resizeImage(blob, "100", "60");
var url = URL.createObjectURL(blob);
img.src = url;
//alert(img.outerHTML);
//startElement.appendChild(img);
$(startElement).append("<div class='row' style='border:1px solid black'><div class='col-xs-10'>" +
img.outerHTML +
"</div>" +
"<div class='col-xs-1' style='padding-top:20px'>" +
"<img src='../Images/delete.png' alt='Delete' class='taskimage'>" +
"</div></div>"
);
return;
}).catch(function () {
console.log("No attachment for doc._id: " + doc._id + " and key: " + key);
})
}
return;
}).then(function () {
resolve();
}).catch(function (err) {
console.log("Image not there for id: " + id);
showMsg("Image not there for id: " + id);
reject(err);
})
}); // end of promise
}
从这段代码调用它:
readAllImagesFromPouch("006", "divImages").then(function () {
}).catch(function (err) {
console.log("In catch for readAllImagesFromPouch with err: " + err);
})
谢谢,
汤姆
答案 0 :(得分:0)
首先,避免使用promise构造函数反模式。当DB_TaskImages.get
返回一个承诺时,您不需要创建一个
其次,你的for...in
循环启动了一堆异步任务 - 但你实际上并没有等待它们完成
可能会重写您的代码:
function readAllImagesFromPouch(id, imageDisplay) {
var startElement = document.getElementById(imageDisplay);
var image = "";
// Get all attachments for this id
return DB_TaskImages.get(id, {
attachments: true
})
.then(function(doc) {
// a promise to chain to - all following tasks will be performed in series, not parallel - this can be changed
var promise = Promise.resolve();
Object.keys(doc._attachments).forEach(function(key) {
promise = promise.then(function() {
return DB_TaskImages.getAttachment(doc._id, key)
.then(function(blob) {
var img = document.createElement('img');
blob = resizeImage(blob, "100", "60");
var url = URL.createObjectURL(blob);
img.src = url;
//alert(img.outerHTML);
//startElement.appendChild(img);
$(startElement).append("<div class='row' style='border:1px solid black'><div class='col-xs-10'>" +
img.outerHTML +
"</div>" +
"<div class='col-xs-1' style='padding-top:20px'>" +
"<img src='../Images/delete.png' alt='Delete' class='taskimage'>" +
"</div></div>"
);
return;
})
.catch(function() {
console.log("No attachment for doc._id: " + doc._id + " and key: " + key);
})
});
});
return promise;
})
.catch(function(err) {
console.log("Image not there for id: " + id);
showMsg("Image not there for id: " + id);
throw err;
})
}
以上代码会串联调用DB_TaskImages.getAttachment(doc._id, key)
。
如果您可以并且想要并行执行DB_TaskImages.getAttachment(doc._id, key)
,则代码需要更多工作
function readAllImagesFromPouch(id, imageDisplay) {
var startElement = document.getElementById(imageDisplay);
var image = "";
// Get all attachments for this id
return DB_TaskImages.get(id, {
attachments: true
})
.then(function(doc) {
return Promise.all(Object.keys(doc._attachments)
.map(function(key) {
return DB_TaskImages.getAttachment(doc._id, key)
// an error here should NOT reject the Promise.all, so handle the error and return undefined
.catch(function() {
console.log("No attachment for doc._id: " + doc._id + " and key: " + key);
})
})
);
})
.then(function(blobs) {
return blobs.filter(function(blob) {
// a failed .getAttachment results in an undefined result here, so ignore it
return blob !== undefined;
}).forEach(function(blob) {
var img = document.createElement('img');
blob = resizeImage(blob, "100", "60");
var url = URL.createObjectURL(blob);
img.src = url;
$(startElement).append(
"<div class='row' style='border:1px solid black'>" +
"<div class='col-xs-10'>" +
img.outerHTML +
"</div>" +
"<div class='col-xs-1' style='padding-top:20px'>" +
"<img src='../Images/delete.png' alt='Delete' class='taskimage'>" +
"</div>" +
"</div>"
);
});
})
.catch(function(err) {
console.log("Image not there for id: " + id);
showMsg("Image not there for id: " + id);
throw err;
})
}
答案 1 :(得分:0)
这可能不是正确的方法,但我想显示我更改的代码,看看这是否是正确的方法。这实际上是@jaromandaX回答的另一个问题的一部分。
这是同样的问题 - 如何处理承诺中的承诺。
查看你的代码resizeImage代码有一个问题,因为blob不是真正的blob,我想,这就是为什么我必须在我的另一个例子中使用blobutil。这真的是一个如何处理这个承诺的问题 - 如果我需要这样做的话。
我的旧代码是:
function resizeImageOld(blob, maxWidth, maxHeight) {
// Set img src to ObjectURL
var showImage = document.createElement('img');
var url = URL.createObjectURL(blob);
showImage.src = url;
var newImage;
showImage.onload = function () {
URL.revokeObjectURL(showImage.src);
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var MAX_WIDTH = maxWidth, maxHeight;
var MAX_HEIGHT = 60;
var width = showImage.width;
var height = showImage.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(showImage, 0, 0, width, height);
newImage = canvas.toDataURL("image/png");
}
return newImage;
}
将其作为承诺是一种在处理另一个图像之前将blob调整大小并附加到DOM的方法。这样它就不会发生onload事件。
我把它改为:
function resizeImage(blob, maxWidth, maxHeight) {
// Set img src to ObjectURL
return new Promise(function (resolve, reject) {
var showImage = document.createElement('img');
var url = URL.createObjectURL(blob);
var newImage;
showImage.onload = function () {
URL.revokeObjectURL(showImage.src);
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var MAX_WIDTH = maxWidth, maxHeight;
var MAX_HEIGHT = 60;
var width = showImage.width;
var height = showImage.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(showImage, 0, 0, width, height);
newImage = canvas.toDataURL("image/png");
resolve(newImage);
}
showImage.src = url;
})
}
然后我改变了你的代码,现在将这个承诺调用到以下内容并想看看这是否是正确的处理方式,或者它是否会跳出承诺继续并在它经过后再回来其他图像。它似乎更好但不确定。
您的代码:
function readAllImagesFromPouch(id, imageDisplay) {
var startElement = document.getElementById(imageDisplay);
var img = "";
var imgBlob;
var base64str;
var fileName;
ClearImagePanel();
// Get all attachments for this id
return DB_TaskImages.get(id, { attachments: true }).then(function (doc) {
// a promise to chain to - all following tasks will be performed in series, not parallel - this can be changed
var promise = Promise.resolve();
Object.keys(doc._attachments).forEach(function (key) {
promise = promise.then(function () {
return DB_TaskImages.getAttachment(doc._id, key).then(function (blob) {
img = document.createElement('img');
return resizeImage(blob, "100", "60").then(function(blob) {
var url = URL.createObjectURL(blob);
img.src = myUrl;
$(startElement).append(img.outerHTML);
})
}).catch(function (err) {
alert("No attachment for doc._id: " + doc._id + " and key: " + key);
})
});
});
return promise;
}).catch(function (err) {
console.log("Image not there for id: " + id);
showMsg("Image not there for id: " + id);
throw err;
})
}
这是对的还是你之前提到过的那种反模式?
我还有另外两个我无法在其他地方找到的问题。
关于链的初始承诺(在这种情况下为DB_TaskImages.getAttachment),我们是否做了&#34;返回&#34;因为我们回到了以下&#34;然后&#34;?我不确定,因为我看过有回报的例子和其他没有回复第一个承诺的例子。
在我的例子中,对于&#34;返回resizeImage&#34;我承诺,在它之后我需要一个.then以及它吗?我注意到,在你做了#34;返回承诺&#34;之后,没有。然后有一个问题。
好奇。
感谢。