Using async/await JS functionality with 'cchipPrintLoop'
The functionality described in this article can only be used with pdfChip versions 2.6.092 and higher, which have an updated WebKit HTLM rendering engine.
The simplest idea of cchipPrintLoop()
is to be a simple loop to modify and print document multiple times:
function cchipPrintLoop() {
for (d of data) {
setData(d);
cchip.printPages();
}
}
Unfortunately, the page might not be ready for printing just after the setData
call (e.g. images not loaded, layout not fully updated, etc.).
So we need to wait until the page is ready for printing by passing a callback to cchip.onPrintReady
.
This works, but the simple loop is gone:
function cchipPrintLoop() {
printNext(0);
}
function printNext(i) {
if(i > 0)
cchip.printPages();
if(i < data.length) {
setData(data[i]);
cchip.onPrintReady(() => printNext(i+1));
}
}
A simple loop turns into a kind of "async recursion", making it harder to tell what's going on at first glance.
Modern async/await syntax allows much simpler control flow:
async function cchipPrintLoop() {
for (d of data) {
setData(d);
await new Promise(cchip.onPrintReady);
cchip.printPages();
}
}
Now we have a simple for-loop again, but with an additional async
keyword and an await new Promise(...)
code line.
For convenience, pdfChip 2.6.094 or higher introduces a new built-in function for promise creation: cchip.printReadyPromise
, which is defined as follows:
cchip.printReadyPromise = () => new Promise( cchip.onPrintReady );
With the help of cchip.printReadyPromise
, the print loop becomes slightly simpler:
async function cchipPrintLoop() {
for (d of data) {
setData(d);
await cchip.printReadyPromise();
cchip.printPages();
}
}
Example: A more complex scenario
Here’s a sample with callbacks and complex control flow (including 2 callbacks and an extra argument in the setData
function):
function setData(d, printNextCallback) {
var [barcodeElement, minh] = setBarcode(d);
cchip.onPrintReady( () => {
setupPage(barcodeElement, d, minh);
cchip.onPrintReady( printNextCallback );
})
}
function printNext(i) {
if(i > 0)
cchip.printPages(1);
if(i < data.length)
setData(data[i], () => printNext(i+1) );
function cchipPrintLoop() {
printNext(0);
}
Code with async
, simple linear control flow (no callback, no extra argument, but extra ‘async/await' keywords):
async function setData(d) {
var [barcodeElement, minh] = setBarcode(d);
await printReady();
setupPage(barcodeElement, d, minh);
}
async function cchipPrintLoop() {
for (let d of data) {
await setData(d);
await cchip.printReadyPromise();
cchip.printPages();
}
}
Note: While async/await code is simpler and easier to manage, it does require a deeper understanding of JavaScript to avoid potential mistakes.