[英]Javascript for loop, wait for function callback
我有一个for循环,它本身调用一个函数。 该函数具有一个回调,但是for循环不会等待其完成并继续工作。
for循环实际上是如此快地完成,以至于在第一个函数调用完成之前完成了下一个要在for循环中填充的文档的操作。
这是我实际使用的呼叫的内容,其中images是一个包含图像外部URL的数组:
// New jsPDF Document
var doc = new jsPDF();
doc.setFontSize(12);
// For each image we add the image to the document as an image
for (var index = 0; index < images.length; index++) {
// We only add pages after the first one
if (index !== 0) {
doc.addPage();
}
// This puts the URL of the active element at the top of the document
doc.text(35, 25, images[index].path);
// Call to our function, this is the 'skipped' portion
convertImgToDataURLviaCanvas(images[index].path, function(base64Img) {
console.log('An image was processed');
doc.addImage(base64Img, 15, 40, 180, 180);
});
}
doc.save('demo.pdf');
console.log('Document served!');
我们从数组中获取图像URL,然后添加所有内容。 convertImgToDataURLviaCanvas
函数在此处:
// Gets an URL and gives you a Base 64 Data URL
function convertImgToDataURLviaCanvas(url, callback, outputFormat){
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
canvas = null;
};
img.src = url;
}
在前面的示例中,甚至行doc.text(35, 25, images[index].path);
确实将网址写到页面顶部。 因为那包含在数组中并且沿着迭代器工作。 但是,在将第一个图像添加到我们的文档之前,for循环已完全完成!
使用console.log
您将看到: 'Document served!'
在第一个'An image was processed'
。 我们的目标是将其反转,在Document served!
之前输出每个'An image was processed'
Document served!
出现了。
如何实现此功能?
为了保证图像的顺序,使用诺言很简单
var promises = images.map(function(image, index) {
return new Promise(function(resolve) {
convertImgToDataURLviaCanvas(image.path, function(base64Img) {
resolve(base64Img);
});
});
}
Promise.all(promises).then(function(results) {
results.forEach(function(base64Img, index) {
if (index !== 0) {
doc.addPage();
}
doc.text(35, 25, images[index].path);
console.log('An image was processed');
doc.addImage(base64Img, 15, 40, 180, 180);
});
doc.save('demo.pdf');
console.log('Document served!');
});
为了完整性(尽管未选中)-保证图像顺序并在正确位置放置addPage / text的非承诺方式
var base64 = new Array(images.length); // base64 images held here
images.forEach(function(image, index) {
// Call to our function, this is the 'skipped' portion
convertImgToDataURLviaCanvas(image.path, function(base64Img) {
console.log('An image was processed');
// We only add pages after the first one
base64[index] = base64Img;
done++;
if (done == images.length) {
base64.forEach(function(img64, indx) {
if (indx !== 0) {
doc.addPage();
}
// This puts the URL of the active element at the top of the document
doc.text(35, 25, images[indx].path);
doc.addImage(img64, 15, 40, 180, 180);
}
doc.save('demo.pdf');
console.log('Document served!');
}
});
}
一种方法如下
var done = 0; // added this to keep counf of finished images for (var index = 0; index < images.length; index++) { // We only add pages after the first one if (index !== 0) { doc.addPage(); } // This puts the URL of the active element at the top of the document doc.text(35, 25, images[index].path); // Call to our function, this is the 'skipped' portion convertImgToDataURLviaCanvas(images[index].path, function(base64Img) { console.log('An image was processed'); doc.addImage(base64Img, 15, 40, 180, 180); // added this code, checks number of finished images and finalises the doc when done == images.length done++; if (done == images.length) { // move the doc.save here doc.save('demo.pdf'); console.log('Document served!'); } // end of new code }); }
使用诺言,很容易...
// For each image we add the image to the document as an image var promises = images.map(function(image, index) { // We only add pages after the first one if (index !== 0) { doc.addPage(); } // This puts the URL of the active element at the top of the document doc.text(35, 25, image.path); // Call to our function, this is the 'skipped' portion // this returns a Promise that is resolved in the callback return new Promise(function(resolve) { convertImgToDataURLviaCanvas(image.path, function(base64Img) { console.log('An image was processed'); doc.addImage(base64Img, 15, 40, 180, 180); resolve(index); // doesn't really matter what is resolved }); }); } Promise.all(promises).then(function(results) { doc.save('demo.pdf'); console.log('Document served!'); });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.