Proposal for delay(duration, [data,] callback [,postpone])

Proposal for delay(duration, [data,] callback [,postpone])

I suggest to add a new signature for delay like delay(duration, [data,] callback [,postpone]), allowing to delay soe functionality on dom elements. And if calling .stop() before the duration passes, the callback would effectively be forgotten.

It might seem a crazy idea, but consider the following situation: You would like to auto-save changes that user has made, but do not wan't to make too many AJAX requests. At the moment the code would look like something similar to: (and that is just the frame, no actual work done)

  1. var timeout;
  2. function saveDirty() {
  3.         stopSave();
  4.         // Collect your data and $.ajax()
  5. }
  6. function stopSave() {
  7.         clearTimeout(timeout);
  8.         timeout = 0;
  9. }
  10. function startSave() {
  11.         stopSave();
  12.         timeout = setTimeout(saveDirty, 5000);
  13. }
  14. // And when something gets "dirty" (changed by user), you call:
    startSave();
  15. // And then if no more dirty things in 5 seconds, it finally gets saved

If we had my proposed delay(duration, callback), it would be written like that:

  1. function saveDirty() {
  2.         // Collect your data and $.ajax()
  3. }
  4. // When having something to save:
  5. $('#saver').stop().delay(5000, saveDirty);

Maybe even save us from calling .stop() and when the same callback function get's delayed and it is already in the queue, postpone it as if it was removed and added again, or give a 3rd parameter for optionally postponing. Or maybe to be able to just .undelay(callback) without the need to stop() the full queue.

It could also be used when you need to show something when hovering over a list of items and the cost of showing tha information is a little bigger than just doing a .show(). Maybe you need to call a .ajax() there to pull additional data from server. then you would call it like:

  1. function showInfo(infoDiv, data) {
  2.         $.ajax('get-long-info.php', {
  3.                 id : data.id
  4.         }, function(response) {
  5.                 // show the data in
  6.                 $(infoDiv).html(response).show();

  7.         }, 'html');

  8. }

  9. var $info = $(info);
  10. $('#list .item).mouseover(function() {
  11.         // delay over 500 msec
  12.         // having item ID stored in data
  13.         // using showInfo as callback
  14.         // and postponing previous callback (and effectively using the new data passed)
  15.         $info.delay(500, {
  16.                 id : $(this).data('item-id')
  17.         }, showInfo);
  18. });

There are also other use cases I have thought about and I'm sure, some of you might find something from your past

Having had my idea evolved during writing the post, I'll take together the idea...

delay(duration, [data,] callback(element, data) [,postpone])
duration - As always, the duration to wait for.
data - Optional data object to pass on to the callback function as second parameter.
callback - The function to call. 2 parameter, first being the element on which the callback was delayed on, giving the chance to use like $('#first, #second').delay(duration, callback). And then it would be called on both #first and #second, having first parameter in callback pointing to the #first and #second elements respectively.
postpone - Optional boolean to postpone previously delayed call to the same function. Defaults to true, as I think that would be the point of using the delay at all.

Sorry for the long post, but hopefully it's worth the time.

Please, share your thoughts...