Throttling JS method calls - don’t make useless AJAX requests

November 19th, 2008 by Artūras Šlajus

This technique is used to avoid having a lot of requests when callbacks run.

Let’s say you have some callback that you invoke after user action. For example to fetch new photo in photo gallery browser.

Gallery = Class.create({
  next: function() {
    // Do some stuff such as store photo id.
    this.callback();
  }

  callback: function() {
    // magic AJAX request code here that fetches info and puts it on screen.
  }
});

So user clicks on next button, callback gets invoked, everybody is fine.

But what if user clicks on next button several times rapidly? Or you introduce changing photos by mousewheel? You get a lot off callbacks (lets say 5) when really you need the last one. And nobody likes useless server load.

What shall we do? I’ll show you the code:

Gallery = Class.create({
  next: function() {
    // Do some stuff such as store photo id.
    setTimeout(this.generateCallback(), 100);
  }

  generateCallback: function() {
    var current = this.photoId;
    return function() {
      if (current == this.photoId) this.callback();
    }.bind(this);
  },

  callback: function() {
    // magic AJAX request code here that fetches info and puts it on screen.
  }
});

So how does this work? Each time you select next image, a generateCallback() is invoked. It stores current photo id in current - a local variable only available to that method invocation. It also returns an anonymous function that is bound to Gallery instance (so this in that function means same as this in next()).

So when user rapidly clicks on next 5 times, 5 functions are generated and they’re going to be invoked after 100ms each. But why don’t they run all?

It’s because of if (current == this.photoId). Because current is local it stores the value of photoId when generator function was invoked. And because that function is bound to this this.photoId is the id set by last next() invocation - the value that we need fetching.

I hope it was clear (thou I think it was not :)). Inspired by A JavaScript Module Pattern.

BTW: some oil into Prototype/jQuery wars - can you do such things with jQuery?

Antireklama

November 17th, 2008 by Artūras Šlajus

Marių žaliosios alyvuogės be kauliukų… Šlykštesnių turbūt nesu ragavęs. Persūdytos ir karčios kažkokios.

Niekam nepatariu pirkti… 4lt i šiukšlių dėžę :)

Ką aš šiandien sužinojau

November 15th, 2008 by Artūras Šlajus
  1. Jog Opera ignoruoja event.stop() keydown įvykio tipui, tad sekmės bindinant actionus prie rodyklių, +/- ar panašių klavišų.
  2. Jog IE lūžta ir atsisako renderint puslapį, jeigu pabandai observinti kokį nors įvykį prieš domready. Sprendimas: document.observe(’dom:loaded’, this.bindEvents.bind(this));
  3. Jog Safari/Chrome atkakliai ignoruoja overflow: hidden ir užduotą div’o aukštį…

Whatever Hover with Prototype that actually works.

November 14th, 2008 by Artūras Šlajus

Or at least only one I know that works on complex CSS like “div.foo div.bar ul li:hover a img” or “div.foo ul#omg:hover li”.

Written with Prototype 1.6.0.2 or something

    // IE6 whatever-hover
    function whatever_hover() {
      if (! Prototype.Browser.IE)
        return;

      // We will replace such kind of hovers
      // Element hover: div:hover a -> div.hovered a
      // Class hover:   div.foo:hover a -> div.foo_hovered a
      // ID hover:      div#foo:hover a -> div.foo_hovered a
      var elementH = /(^|\s)([^\s\.\#]+):hover/i;
      var classH = /(^|\s)(\w*)([#\.])([^\s\.#]+):hover/i;
      $A(document.styleSheets).each(function(stylesheet) {
        $A(stylesheet.rules).each(function(rule) {
          if (
            rule.selectorText.match(/:hover/i) &&
            // a:hover is supported on it's own
            ! rule.selectorText.match(/(^|\s)a:hover/i) &&
            ! rule.style.cssText.blank() // IE chokes on empty rules
          ) {
            var newSelector, newClassName;
            if (rule.selectorText.match(elementH)) {
              newSelector = rule.selectorText.gsub(elementH, ' #{2}.hovered');
              newClassName = 'hovered';
            }
            else {
              newSelector = rule.selectorText.gsub(classH, " #{2}.#{4}_hovered");
              newClassName = rule.selectorText.match(classH)[4] + '_hovered';
            }
            stylesheet.addRule(newSelector, rule.style.cssText);
            $$(rule.selectorText.split(':').first()).each(function(tag) {
              tag.observe('mouseover', function() {
                tag.addClassName(newClassName);
              });
              tag.observe('mouseout', function() {
                tag.removeClassName(newClassName);
              });
            });
          }
        });
      });
    }

KTU informatikai - kalikai?

November 11th, 2008 by Artūras Šlajus

Kad stojant į mediciną reikia turėti gerą atmintį - žinojau, bet į KTU informatiką?

Kompiuterių architektūros kolis: aš - 1.5/4, Mikis - 2/4, Jho, kuris pamtė medžiagą gal 2 val prieš kolį, bet turi afigiet fotografinę atmintį - 2.5.

Nu ir tipo pofig, ką tu ten supranti, ar ko ne. Svarbu mintinai mokėt 7 šiuolaikinio kompiuterio virtualizacijos lygius. Oh yeah…

P.S.: tas pats su programavimo inžinerija. Klausimas: realaus laiko sistemos. Įžanga. Temos. Nu pezdec pezdec…

Nebėra A. Valio :(

November 4th, 2008 by Artūras Šlajus

Kad ir kaip bebūtų gaila, bet KTU informatikos fakulteto studentų numylėtas dėstytojas A. Valys jau nebešmėžuos gyvųjų tarpe :(

Mes pasigesime tavo juokelių ir optimizmo… Ramaus Tau poilsio…

Ruby bindings got easier!

November 1st, 2008 by Artūras Šlajus

Ruby’s New FFI Library @ Ruby Inside

Megamiesto blokada

October 31st, 2008 by Artūras Šlajus

Jonavos g. / Šiaurės pr. sankryža

Eh, galim su Vilniumi lygiuotis ;) Visam mieste kamščiai. O viskas dėl to, kad šiandien megoje iki 66% nuolaidos! Eh, matyt nepagalvojo marketingo liaudis ką jie padarys :D

Knygorama!

October 30th, 2008 by Artūras Šlajus

Sumąsčiau, kad reikia žymėtis visas knygas, kurias buvau perskaitęs ir pareiškinėti trumpą nuomonę. Tiesiog šiaip, dėl įdomumo :)

Dead simple: accordion

October 27th, 2008 by Artūras Šlajus

Here you go. My own version of accordion script for prototype/scriptaculous.