From: pedz on
From my original post:

> The problem is that steps 2 and 5 are done by setting up call back
> handlers and so the result is that I do not get to "see" the list of
> steps.

Part of my original "I need" list was #4 -- perhaps I need to just
think differently.

But my problem is that I'd like to be able to follow the flow of a
program using async events like I do other programs. I look down a
list of statements and see the sequence of steps being taken.

Granted, that is not necessary. I've just come to be use to it.

Wouldn't be more intuitive if I could write:

result = doSomeCall();
if (result == good)
beHappy();
else
beSad();

where doSomeCall() starts an asynchronous sequence of steps and the
end result is returned?
From: Thomas 'PointedEars' Lahn on
pedz wrote:

> But my problem is that I'd like to be able to follow the flow of a
> program using async events like I do other programs. I look down a
> list of statements and see the sequence of steps being taken.
>
> Granted, that is not necessary. I've just come to be use to it.

In that case I suggest you use the script consoles built into many browsers,
tools like Firebug, other debuggers (set a breakpoint in the callback), or
use a logging feature in the callback (which, again, is often provided as a
built-in with console.log()).

> Wouldn't be more intuitive if I could write:
>
> result = doSomeCall();
> if (result == good)
> beHappy();
> else
> beSad();
>
> where doSomeCall() starts an asynchronous sequence of steps and the
> end result is returned?

No, because "asynchronous" implies that the result may not yet be available
when doSomeCall() returns.


HTH

PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
From: Scott Sauyet on
On Jun 13, 6:38 pm, pedz <pedz...(a)gmail.com> wrote:
> [ ... ]
> This got me thinking about a JS library which would create a thing.  I
> don't want to call it a "thread" nor a "context" because both of those
> terms have so much meaning.  So, for now, I'm going to call it a VSF
> for Virtual Stack Frame. [ ... ]

If I have it right, both David and Thomas were somewhat misdirected by
your talk of the testing framework. You are not looking particularly
to rewrite the testing framework but to create a tool that helps you
make a list of possibly asynchronous calls look as much like a list of
synchronous ones as possible, right?

A don't know of a tool out there, but I can imagine the start to an
interface to building one, but I get stuck very quickly at forks. How
do you handle, say, an AJAX call (sorry Thomas!) that fails? Do you
add conditionals? Do you then need loops? Are you already on your
way then to a DSL?

Putting that aside for the moment, would an interface like the implied
Sequencer in the following meet your requirements?

var sequence = new Sequence(
function() {/* set up AJAX call */},
function() {/* perform AJAX call 1 */}, // #1
function() {/* update DOM *},
function() {/* perform AJAX call 2 */}
function() {/* perform further DOM updates */}
);
sequence.start();

where the function labeled #1 above might look like this:

function(data) {
var theSeq = this;
MyAjaxFunction({
url: 'myScript.php',
method: 'POST',
postData: {a : data.a, b:data.b},
success: function(results) {theSeq.next(results)},
failure: function(error) {theSeq.abort()}
})
}

Such a constructor would generate objects that have methods such as
start, next, and abort. Each function in the sequence is called with
"this" bound to the sequence itself. If the function returns true,
then the next function is called immediately. Otherwise the sequence
is paused until its "next" method is called. You could use a property
of the sequence object to hold data that needs to be shared among the
steps,

Is that close to what you're looking for? If so, it doesn't sound
particularly difficult to write. But if you start talking about
branching or looping, it starts to sound more like language design,
like a much larger undertaking.

--
Scott
From: pedz on
On Jun 13, 8:38 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
> On Jun 13, 6:38 pm, pedz <pedz...(a)gmail.com> wrote:
>
> > [ ... ]
> > This got me thinking about a JS library which would create a thing.  I
> > don't want to call it a "thread" nor a "context" because both of those
> > terms have so much meaning.  So, for now, I'm going to call it a VSF
> > for Virtual Stack Frame. [ ... ]
>
> If I have it right, both David and Thomas were somewhat misdirected by
> your talk of the testing framework.  You are not looking particularly
> to rewrite the testing framework but to create a tool that helps you
> make a list of possibly asynchronous calls look as much like a list of
> synchronous ones as possible, right?
>
> A don't know of a tool out there, but I can imagine the start to an
> interface to building one, but I get stuck very quickly at forks.  How
> do you handle, say, an AJAX call (sorry Thomas!) that fails?  Do you
> add conditionals?  Do you then need loops?  Are you already on your
> way then to a DSL?
>
> Putting that aside for the moment, would an interface like the implied
> Sequencer in the following meet your requirements?
>
>   var sequence = new Sequence(
>     function() {/* set up AJAX call */},
>     function() {/* perform AJAX call 1 */}, // #1
>     function() {/* update DOM *},
>     function() {/* perform AJAX call 2 */}
>     function() {/* perform further DOM updates */}
>   );
>   sequence.start();
>
> where the function labeled #1 above might look like this:
>
>   function(data) {
>     var theSeq = this;
>     MyAjaxFunction({
>       url: 'myScript.php',
>       method: 'POST',
>       postData: {a : data.a, b:data.b},
>       success: function(results) {theSeq.next(results)},
>       failure: function(error) {theSeq.abort()}
>     })
>   }
>
> Such a constructor would generate objects that have methods such as
> start, next, and abort.  Each function in the sequence is called with
> "this" bound to the sequence itself.  If the function returns true,
> then the next function is called immediately.  Otherwise the sequence
> is paused until its "next" method is called.  You could use a property
> of the sequence object to hold data that needs to be shared among the
> steps,
>
> Is that close to what you're looking for?  If so, it doesn't sound
> particularly difficult to write.  But if you start talking about
> branching or looping, it starts to sound more like language design,
> like a much larger undertaking.

Thank you Scott... you helped a lot.

Yes. That is what I am talking about.

As far as errors, the first step is to have all the handlers funnel
back to a common point and that point returns a single "result". Care
would be needed for the case that two handlers fire but lets not go
there yet. Your approach of having a next and an abort I like too.

The most primitive control structure would be a "skip if" statement.
This provides a crude but still fairly readable if/then/else
structure. The "skip if" would skip one statement if the condition is
true. The next statement is usually a "branch to error code" or
"return error code up to the next higher level". A DSL for more
sophisticated loops could build on top of this simple structure.

One thing I thought about between posts is the Sequence needs a way to
start with at least one input argument. But, that could be done via
the get and set interfaces to the "Sequence local" variables.
From: Thomas 'PointedEars' Lahn on
Thomas 'PointedEars' Lahn wrote:

> pedz wrote:
>> Wouldn't be more intuitive if I could write:
>>
>> result = doSomeCall();
>> if (result == good)
>> beHappy();
>> else
>> beSad();
>>
>> where doSomeCall() starts an asynchronous sequence of steps and the
>> end result is returned?
>
> No, because "asynchronous" implies that the result may not yet be
> available when doSomeCall() returns.

I think you might be looking for something like

doSomeCall(beHappy, beSad);

But that alone will not help with your "problem".


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16