在将blob提交到服务器之前等待canvas.toDataURL()完成

时间:2018-04-19 10:25:57

标签: javascript jquery pdf.js

我这里有一个项目要求,使用文件输入接受文件并在画布上显示它,同时将其作为blob处理并发送到后端进行处理。根据文件类型,我可以使用不同的进程。

如果文件类型是pdf,它将使用pdf.js进行处理,并且pdf图像将显示在画布上,同时将文件转换为blob并发送到后端进行处理。到目前为止,这仅适用于单页pdf,因为我可以直接将画布数据转换为blob并在toDataURL完成后直接发送。

但是对于多页pdf,我在每页上运行多个toDataURL时遇到问题。我的想法是,当我使用pdf.js的getPage迭代每个页面时,我将在画布上显示该页面,并将画布图像作为blob并将其推入数组。处理完所有页面并将所有blob推入阵列后,我会将其发送到后端进行处理。

var __TOTAL_PAGES, __ISMULTIPLEPAGE, __CANVAS = undefined;
var __MULTIPAGEHOLDER = [];

function showPDF(pdf_url) {
    PDFJS.getDocument({url: pdf_url}).then(function (pdf_doc) {
        __TOTAL_PAGES = pdf_doc.numPages;
        __ISMULTIPLEPAGE = __TOTAL_PAGES > 1 ? true : false;

        // Show the first page
        for (var i = 0; i < __TOTAL_PAGES; i++){
            $('#parentId').append('<canvas id="canvas-'+(i+1)+'"></canvas>');

            showPage(i+1);
    }

    }).catch(function (error) {
    /* Insert any error handling here */
    });
}

function showPage(page_no) {
    __PDF_DOC.getPage(page_no).then(function (page) {
        /* Some setup here */

        var renderContext = {
            canvasContext: /* Some value */,
            viewport: /* Some value */
        };

        // Render the page contents in the canvas
        page.render(renderContext).then(function () {

            __CANVAS = document.getElementById('canvas-'+page_no);

            // $('#go_pdf').click();
            if (__ISMULTIPLEPAGE){
                var thisPageURL = __CANVAS.toDataURL();
                    thisPage = dataURLtoBlob(thisPageURL);
                    __MULTIPAGEHOLDER.push(thisPage);

                if (__MULTIPAGEHOLDER.length === __TOTAL_PAGES){
                    // Once all blob are ready then only will submit to backend
                    submitPDFtoBackend(__MULTIPAGEHOLDER);
                }
            } else {
                var pdfData = [];
                if (pdfCanvas != null) {
                    var data = __CANVAS.toDataURL();
                    pdfData.push(dataURLtoBlob(data));
                }

                submitPDFtoBackend(pdfData);
            }
        });
    });
}

但上述内容并不符合我的预期,因为有时候,即使toDataURL仍在运行,仍会调用submitPDFtoBackend方法。我只希望在所有toDataURL完成后调用submitPDFtoBackend,并且所有blob都已被推送到数组。

我读过将toDataURL进程作为一个promise,因此可以使用$ .when对promises执行submit方法,但我不确定这是否可行。像

这样的东西
$.when.apply(null, promise).then(function() {
    submitPDFtoBackend(__MULTIPAGEHOLDER);
});

但我不确定如何做到这一点。

由于

1 个答案:

答案 0 :(得分:1)

  1. 您可以直接通过canvas.toBlob转到blob,而不是转到dateURL然后再转到blob。
  2. 要检查blob是否准备好,您可以将其捕获到img元素的onload处理程序中,然后在onload处理程序中调用submitPDFToBackend。以下代码段直接来自mdn
  3. var canvas = document.getElementById(&#39; canvas&#39;);

    canvas.toBlob(function(blob) {
    var newImg = document.createElement('img'),
    url = URL.createObjectURL(blob);
    newImg.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(url);
    };
    newImg.src = url;
    document.body.appendChild(newImg);
    

    });