1

I'm trying to dynamically create PDFs on a webserver using PHP/wkhtmltopdf, which involves sending the PDF-generation process to the background in order to prevent the page timing out.

To check whether the job has completed successfully, I've used Javascript (which I suck at) and more specifically jQuery/AJAX to continuously query the server looking to see if wkhtmltopdf's process has ended. If its still running, the PHP script returns nothing and simply exits. If the process has ended successfully, a html link to the PDF is generated and then dumped into a <div></div>.

All the server side code works flawlessly however I'm stuck on the Javascript component. The code below kinda works but instead of the timer stopping after a PDF has been generated, it continues to query the server. How do I get it to stop?

$('#pdfmodal').on('shown', function () {
 pdf(); // fire PDF generation process function
 (function worker() {
 $.ajax({
 url: 'pdfpidcheck.php', 
 success: function(data) {
 if(data == ''){
 // Schedule the next request if nothing returned (i.e. still running)
 setTimeout(worker, 5000); 
 } else {
 // dump link to pdf
 $('.pdfmodal').html(data);
 }
 }
 });
 })();
})
jfriend00
711k104 gold badges1.1k silver badges1k bronze badges
asked Dec 13, 2013 at 22:21
2
  • Reason is you are invoking pdf() which inturn invokes it again with timeout and it goes on and on. Commented Dec 13, 2013 at 22:23
  • The nature of asynchronous code is to keep going independently of the main script, for as long as it takes. What you probably need to do is redesign your code so that JavaScript makes one AJAX call to one PHP script which (a) initiates the PDF creation and then (b) returns the link to it. Commented Dec 13, 2013 at 22:23

1 Answer 1

2

To stop a timer, you just remember the returned value from setTimeout() and call clearTimeout() on it.

var id = setTimeout(fn, 5000);
// then some time later
clearTimeout(id);

In the code you've shown us, this should not be an issue unless you are calling worker() from some other place than what you show us or unless the .on() handler gets called a second time while a PDF is being created. Your current code doesn't look like it knows how to handler two PDFs being created at the same time or a second even triggered while the first one is still processing.

You could protect against multiple timers running like this:

$('#pdfmodal').on('shown', function () {
 var modal = $(this);
 pdf(); // fire PDF generation process function
 (function worker() {
 $.ajax({
 url: 'pdfpidcheck.php', 
 success: function(data) {
 var timer = modal.data(timer);
 if(data == ''){
 // make sure we never have more than one timer running
 if (timer) clearTimeout(timer);
 // Schedule the next request if nothing returned 
 // (i.e. server process still running)
 timer = setTimeout(worker, 5000); 
 // save timer for later use
 modal.data("timer", timer);
 } else {
 // clean up timer data
 if (timer) clearTimeout(timer);
 modal.removeData("timer");
 // dump link to pdf
 $('.pdfmodal').html(data);
 }
 }
 });
 })();
})
answered Dec 13, 2013 at 22:23
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks, that worked! I'm not too worried about the possibility of having two instances running as its very unlikely in my application. At the server side, each pdf is given a unique id, so if the user did trigger another PDF generation modal at the same page, all it'll do is create a new PDF and overwrite the link in the div. As soon as they migrate to another page, the javascript is physically removed from the DOM and a new instance of the above function generated. Thanks again. :)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.