From: Jorge on
On Apr 19, 9:20 am, Johannes Baagoe <baa...(a)baagoe.com> wrote:
> Jorge :
>
> > No, no no.
>
> :) Got it. I was familiar with the '&&' idiom in shell scripts and Perl,
> but it had never occurred to me that it could be used outside of
> `if` and `while` conditions in javascript, too.

JavaScript is the C of the dynamic, high-level languages. And coming
from where you seem to come from, there's just 3 things that you must
learn in order to understand it fully: object prototypes, closures,
and functions as first-class citizens. Learn them and you'll end up
loving it. Don't, and you'll end up hating it.
--
Jorge.
From: Jorge on
On Apr 19, 8:48 am, Jorge <jo...(a)jorgechamorro.com> wrote:
> On Apr 19, 6:48 am, Johannes Baagoe <baa...(a)baagoe.com> wrote:
>
>
>
>
>
>
>
> > I see. What I had in mind was more basic, like
>
> >   for (var i = 0; i < someLargeishNumber; i++) {
> >     someJustAcceptablySlowFunction();
> >     yield();
> >   }
>
> > or even
>
> >    someJustAcceptablySlowFunction();
> >    yield();
> >    anotherJustAcceptablySlowFunction();
> >    yield();
>
> > etc.  
>
> But normally you would have put this code inside a function, wouldn't
> you ?

The idea is that you should consider the function inside which you'd
normally put your code, as if it were the "contextContainer" in my
example.
--
Jorge.
From: Johannes Baagoe on
Jorge :

> The idea is that you should consider the function inside which you'd
> normally put your code, as if it were the "contextContainer" in my
> example.

Yes, I think I get it.

But what are the advantages of your solution with respect to what I
came up with before starting this thread ? viz.: (it has become
a little more complicated since then)

function time1(element) {
// where the actual calculation is done
}

function time(elements) {
if (elements.length === 0) {
return;
}

var element = elements.shift();
window.setTimeout(time1, 0, element);
window.setTimeout(time, 0, elements);
}

I could put time1 inside time for aesthetic reasons, but otherwise ?

--
Johannes
From: Bwig Zomberi on
Jorge wrote:
> You're right: there's no better way. Currently only Opera renders DOM
> changes to the screen in parallel with JS execution (in a separate
> thread, or process, or whatever).

This is definitely true.

I wrote a javascript function to read e-mail addresses off one textarea
box and insert valid ones into another textarea box. I used over 14000
e-mail addresses in IE, Firfox, Safari, Chrome, and Opera.

Opera took a long time to process the e-mail addresses but it remained
responsive all the time. Other browsers were not so. Result was:

Safari > Chrome > Firefox > Opera > IE.


Except Opera, none of the other browsers updated the web page while they
ran the function. Only Opera allowed me to click inside the textarea box
and scroll down to the last inserted e-mail addresses during that time.

They optimized the JS engine and left the layout engine far behind. Only
Opera has kept them together.






--
Bwig Zomberi
From: Jorge on
On Apr 19, 10:24 am, Johannes Baagoe <baa...(a)baagoe.com> wrote:
> Jorge :
>
> > The idea is that you should consider the function inside which you'd
> > normally put your code, as if it were the "contextContainer" in my
> > example.
>
> Yes, I think I get it.
>
> But what are the advantages of your solution with respect to what I
> came up with before starting this thread ? viz.: (it has become
> a little more complicated since then)
>
>   function time1(element) {
>     // where the actual calculation is done
>   }
>
>   function time(elements) {
>     if (elements.length === 0) {
>       return;
>     }
>
>     var element = elements.shift();
>     window.setTimeout(time1, 0, element);
>     window.setTimeout(time, 0, elements);
>   }
>
> I could put time1 inside time for aesthetic reasons, but otherwise ?

Here the only valuable context that you need to keep across
setTimeout()s is the array `elements` (the parameter to time()).
`elements` belongs to time()'s context, that's why I call time() the
"contextContainer", and that context is preserved in the closure
created by loop(), that's why I call loop() "iCarryTheContext".

Therefore, time() being the contextContainer, I would write it so:

function time /*contextContainer*/ (elements) {
function time1 (element) { ... }
function resetHandlers () { ... }

(function loop /*iCarryTheContext*/ (e) {
if (e= elements.shift()) reset(e), time1(e);
if (elements.length) setTimeout(loop, 0); else resetHandlers();
})();
}

I like to "compress" the code, uncompressed loop() would look like
this:

function loop () {
var element= elements.shift();
if (element) {
reset(element);
time1(element);
}
if (elements.length) {
setTimeout(loop, 0);
} else {
resetHandlers();
}
}

loop();
--
Jorge.