Hi,

That fiddle didn't work for me, but when I forked it and moved the
message stuff out to its own function (you were working way too hard
there with the new Element thing, btw) it started working. Here's the
fork:
http://jsfiddle.net/NMPyV/1/

Let me guess: You're using Internet Explorer to test, right? Because
when you click a button twice in rapid succession on IE, it registers
a click followed by a dblclick, *not* two separate clicks. On Chrome
or FF, you get two separate clicks (followed by a dblclick). If I
change the button to a text box and hook keydown, or if I hook both
click and dblclick (but the latter only on IE), no matter how close
together my events (keypresses or clicks), they show up, regardless of
which browser I'm using. If the backend is slow (like jsFiddle),
things queue correctly; if not (my local machine), they show up
correctly without being queued. By putting in a short delay on my
local machine, I was able to easily make things queue or not by
clicking faster or slower.

The code probably isn't the way I'd do it (I don't like the fact it
relies on getting a completion event, seems to me that's asking to
stall because 'net communication is...not entirely reliable), but it
should work barring net issues. (I'd probably add some kind of
timeout; if a request has been started but I haven't seen any kind of
completion event at *all* for X time, I'd probably time out the
message. I'd also give them unique IDs so I knew that had happened, if
the completion event showed up later. Etc.)

Here's my very, very slightly modified version of your fiddle (without
event changes, but those are described above):
http://jsfiddle.net/NMPyV/1/

FWIW,

-- T.J.

On Aug 13, 2:07 pm, Moo <stuhlm...@fifty-nine.de> wrote:
> Thanks T.J.,
>
> your code seems to work quite nice. I updated mine with your hints. I
> also removed the alert and replaced it with an update of a container.
> It was used for debugging purposes only.
> I also added a button, to trigger the add-function by hand.
>
> The problem is, that when you click on the button multiple times (e.g.
> 3 times) very quickly, it outputs two messages. 2 were added, 2 were
> sent. If you have a small timeout between clicks (maybe half a
> second), the messages are stored to the queue properly...
> It seems that there is no reliable technique to save all user-inputs
> which were made in short periods of time :(
>
> Here is an updated version:http://jsfiddle.net/zkuMv/2/
>
> Thank you so much and I can understand, that you can't dive into
> detail so much.
> Geetings
> Moo
>
> On 13 Aug., 14:23, "T.J. Crowder" <t...@crowdersoftware.com> wrote:
>
>
>
> > Hi,
>
> > The only remaining problems I'm seeing are that you're using alert
> > (don't do that, append to the body or something, alert does awkward
> > things) and you're using onSuccess now instead of onComplete as you
> > were originally. onComplete is what you want to trigger the next
> > message (Ajax calls *do* fail).
>
> > The queuing seems to work when you use setTimeout to simulate async
> > ajax:http://jsbin.com/egudo3
> > ...but what the actual problem is when you're doing what you're
> > describing, I couldn't say without extensive debugging I'm afraid I
> > don't have time to go into.
>
> > Off-topic: Strongly recommend *not* leaving off semicolons and braces
> > (your add function). You may want to minify later (semicolons) and
> > leaving off braces in my experience (20+ years in C-like syntax) is
> > always more trouble than it's worth. YMMV
>
> > Good luck,
>
> > -- T.J.
>
> > On Aug 13, 10:46 am, Moo <stuhlm...@fifty-nine.de> wrote:
>
> > > Here is a working example:http://jsfiddle.net/zkuMv/
>
> > > On 13 Aug., 11:43, Moo <stuhlm...@fifty-nine.de> wrote:
>
> > > > Hi T.J.,
>
> > > > thank you for your reply. You are right about the idle-flag, I already
> > > > renamed it :)
> > > > I followed your advice and moved up the "idle = false" thing, but it
> > > > does not work so well.
> > > > With a slow connection the code below works fine:
>
> > > > var MessageQueue = Class.create({
> > > >     initialize: function(url) {
> > > >         this.url = url;
> > > >         this.queue = [];
> > > >         this.busy = false;
> > > >     },
> > > >     add: function(message) {
> > > >         if (this.busy) this.queue.push(message)
> > > >         else this.push(message);
> > > >     },
> > > >     push: function(message) {
> > > >         this.busy = true;
> > > >         new Ajax.Request(this.url, {
> > > >             onSuccess: function() {
> > > >                 alert(message);
> > > >                 this.busy = false;
> > > >                 if (this.queue.size() > 0) {
> > > >                     this.push("queued: " + this.queue.shift());
> > > >                 }
> > > >             }.bind(this)
> > > >         });
> > > >     }
>
> > > > });
>
> > > > var mq = new MessageQueue("/ajax_html_echo/");
> > > > mq.add("First");
> > > > mq.add("Second");
> > > > mq.add("Third");
>
> > > > But when the backend is fast and you type the hell out of your
> > > > keyboard, it seems, that the part
> > > > this.push("queued: " + this.queue.shift());
> > > > is never reached. There is no output with "queued:"
>
> > > > My thought was, that when new messages arrive, while a request is in
> > > > progess, to store them until the request is finished. Then all
> > > > messages in the stack should be sent until the busy-flag is set to
> > > > false. Therefore I had it below the if-condition.
>
> > > > I saw that the guys at jQuery use a sentinel "inprogress" which they
> > > > unshift/shift to/from the array. But I don't know if that would be
> > > > helpful here.
>
> > > > It would be super great if you have the time, to have a second look at
> > > > it!
>
> > > > Thank you so much
>
> > > > On 13 Aug., 10:18, "T.J. Crowder" <t...@crowdersoftware.com> wrote:
>
> > > > > Hi,
>
> > > > > Your "idle" flag -- which you seem to use to mean "busy processing a
> > > > > request", which I found *really* confusing at first :-) -- is getting
> > > > > cleared inappropriately whenever you pull something from your queue. I
> > > > > don't know that that's the problem, but it's probably wrong. The error
> > > > > is in your onComplete function:
>
> > > > > if (this.queue.size() > 0) {
> > > > >     console.log("queue-size > 0, so enqueue next item");
> > > > >     this.push("queued: " + this.queue.shift());}
>
> > > > > this.idle = false; // <=== Error if `if` above was true
>
> > > > > If there's something in the queue, you call `push`, which sets the
> > > > > flag, starts a new async request, and returns. But then you clear the
> > > > > flag, so the next time `add` gets called, it'll think it should call
> > > > > `push` rather than `queue.push` even though there's an outstanding
> > > > > request.
>
> > > > > If you just move the `this.idle = false;` line above the `if`
> > > > > statement, it should sort out this issue. Whether it solves the
> > > > > problems you described I can't say, but I suspect it'll solve at least
> > > > > some of them.
>
> > > > > HTH,
> > > > > --
> > > > > T.J. Crowder
> > > > > Independent Software Consultant
> > > > > tj / crowder software / comwww.crowdersoftware.com
>
> > > > > On Aug 12, 7:55 pm, Moo <stuhlm...@fifty-nine.de> wrote:
>
> > > > > > Hi there,
>
> > > > > > I want to ensure, that messages are posted in the order, they come 
> > > > > > in
> > > > > > the stack. My tests at jsFiddle were okay, but with a quick backend
> > > > > > (where the requests are processed very fast) the order is crap.
> > > > > > Sometimes items are posted twice. Is there anybody who can help me
> > > > > > out? Thank you all!
>
> > > > > > var MessageQueue = Class.create({
> > > > > >         initialize: function(url) {
> > > > > >         this.url = url;
> > > > > >         this.queue = [];
> > > > > >         this.idle = false;
> > > > > >         },
> > > > > >         add: function(message) {
> > > > > >         if (this.idle) {
> > > > > >                 console.log("idle, so saved to queue: " + message);
> > > > > >                 this.queue.push(message);
> > > > > >         } else {
> > > > > >                 console.log("not idle, so pushed directly: " + 
> > > > > > message);
> > > > > >                 this.push(message);
> > > > > >         }
> > > > > >         },
> > > > > >         push: function(message) {
> > > > > >         this.idle = true;
> > > > > >         console.log("Ajax.Request will be called now!");
> > > > > >         new Ajax.Request(this.url + "&message=" +
> > > > > > encodeURIComponent(message), {
> > > > > >                 onComplete: function() {
> > > > > >                         console.log("successfully sent: " + 
> > > > > > message);
> > > > > >                 if (this.queue.size() > 0) {
> > > > > >                         console.log("queue-size > 0, so enqueue 
> > > > > > next item");
> > > > > >                         this.push("queued: " + this.queue.shift());
> > > > > >                 }
> > > > > >                 this.idle = false;
> > > > > >                 }.bind(this)
> > > > > >         });
> > > > > >         }
>
> > > > > > });- Zitierten Text ausblenden -
>
> > > > > - Zitierten Text anzeigen -- Zitierten Text ausblenden -
>
> > > > - Zitierten Text anzeigen -- Zitierten Text ausblenden -
>
> > - Zitierten Text anzeigen -

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to