在解决所有诺言之后,我该如何调用函数?我有一个包含三个表的HTML文档。使用html2canvas(),我通过在forEach()循环中对其进行迭代来创建JPG:
var elements = document.querySelectorAll( 'table' );
elements = Array.from( elements );
var zip = new JSZip(),
img = '';
elements.forEach( function( element ) {
html2canvas( element ).then( canvas => {
var styleID = element.getAttribute('id');
img = new Image();
img.src = canvas.toDataURL( 'image/jpeg' );
document.body.appendChild( img );
zip.file( styleID + '.jpg', img.src );
}).then( generateZip );
});
function generateZip () {
// Generate the zip file asynchronously
zip.generateAsync({type:'blob'}).then( function( content ) {
saveAs( content, 'archive.zip' );
});
}
问题是generateZip()被调用了三次,每个循环一次。在解决所有承诺后,如何只一次调用一次generateZip()创建一个zip文件?
答案 0 :(得分:2)
在调用generateZip
方法之前,您可以使用Promise#all来了解所有诺言何时完成。使用Promise#all也很有趣,因为如果一个html2canvas失败,则整个Promise都会失败,并且generateZip将不会被调用。
Promise.all()方法返回一个Promise,当作为可迭代对象传递的所有promise已解决或可迭代对象不包含promise时,该Promise进行解析。它以第一个承诺被拒绝的理由拒绝。
Promise#all在data
回调中返回的then
是您的canvas
s的数组。
var elements = document.querySelectorAll( 'table' );
elements = Array.from( elements );
var zip = new JSZip(),
img = '';
function generateZip () {
// Generate the zip file asynchronously
zip.generateAsync({type:'blob'}).then( function( content ) {
saveAs( content, 'archive.zip' );
});
}
function prepareZip(canvas, element){
var styleID = element.getAttribute('id');
img = new Image();
img.src = canvas.toDataURL( 'image/jpeg' );
document.body.appendChild( img );
zip.file( styleID + '.jpg', img.src );
}
Promise.all(elements.map(element=> html2canvas(element)))
.then(data=>{
data.forEach((canvas, index)=>prepareZip(canvas, elements[index]));
generateZip();
});
不带箭头功能的解决方案:
var elements = document.querySelectorAll( 'table' );
elements = Array.from( elements );
var zip = new JSZip(),
img = '';
function generateZip () {
// Generate the zip file asynchronously
zip.generateAsync({type:'blob'}).then( function( content ) {
saveAs( content, 'archive.zip' );
});
}
function prepareZip(canvas, element){
var styleID = element.getAttribute('id');
img = new Image();
img.src = canvas.toDataURL( 'image/jpeg' );
document.body.appendChild( img );
zip.file( styleID + '.jpg', img.src );
}
Promise.all(elements.map(function(element){ return html2canvas(element); }))
.then(function(data){
data.forEach(function(canvas, index){
prepareZip(canvas, elements[index])
});
generateZip();
});