简体   繁体   中英

Run in the background: threading in Javascript?

I have a series of forms that the user sees in sequence. When the user submits the form, it submits to a PHP file which will do some heavy work based on the submitted values, which might take 10 seconds or more to run, and I don't want my users to have to wait before going to the next form.

Since I don't really need to wait for the PHP to finish (I don't need its results in order to proceed), is it possible to redirect the user to the next page on submit, and submit the form in the background so it doesn't slow the user down?

I've heard that Javascript setTimeout() can mimic threading. Is this an option to make it run in parallel?

My JS function goNext() redirects the user to the next page (but does NOT submit). So would something like this work?

$('#submitButton').click(function() {
    setTimeout(submitForm(), 1);
    goNext();
});

function submitForm() {
    $('#form').submit();
}

Every HTTP request will receive a response. So, in order to tell that your request worked, you would need to get a good response (200) from the server.

In order to do what you are suggesting, I think you should handle this on the server-side.

Use ajax to handle the form asyncronously. I know a library like jQuery allows you to have a callback too which will be called when the data is returned. You can do this too without a library but having one simplifies things.

From their website:

$.ajax({
  url: 'ajax/test.html',
  success: function(data) {
    $('.result').html(data);
    alert('Load was performed.');
  }
});

(Calls are by default asyncronous)

Without a library, you can do something like this:

var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    alert('Ajax returned';
    }
  }
xmlhttp.open("GET", "some_url.txt",true);
xmlhttp.send();

xmlhttp.onreadystatechange= is where you set the "callback" function, but with plain javascript you probably want to check if the ready state is actually the success ready state (as in the example).

No, this won't work. When the user leaves the page (eg by submitting a form), the javascript is terminated, and the next page load creates a fresh javascript context. You can't persist variables or timers over requests with javascript alone.

You could use ajax for this, provided everything happens on the same page, with ajax calls to send form data and wait for the processing to finish, but if the user accidentally closes the page or navigates away while the ajax call is waiting, the processing gets aborted.

A better solution is to separate the uploading, the processing, and the reporting parts on the server ; this could be architected somewhat like this:

  • Set up a task queue on the server. The conventional choice for this would be a database table; processes add a record for each upload that needs to be processed, and alter it to indicate status (new, working, done).
  • The upload handler just reads the uploaded file and adds it to the task queue. Once that's done, the user can safely navigate away.
  • Run a cron job or worker process which at regular intervals looks to see if there are new tasks to be processed; if so, it picks one up (setting its status to 'working'), processes it, and when it's done, updates it.
  • Meanwhile, your web application remembers the job's ID, and polls the server for its status. As soon as it changes to 'done', it notifies the user (if you need feedback after all). Ajax provides the smoothest way for this, otherwise the user will have to refresh every now and then to see what the status of their upload is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM