全部承诺后调用函数

时间:2019-04-02 19:19:54

标签: javascript jquery promise jszip

在解决所有诺言之后,我该如何调用函数?我有一个包含三个表的HTML文档。使用html2canvas(),我通过在forEach()循环中对其进行迭代来创建JPG:

JavaScript

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文件?

1 个答案:

答案 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();
});