MozillaZine

what do you think about inserting a "wait" command into JS?

Discuss how to use and promote Web standards with the Mozilla Gecko engine.
yno1
 
Posts: 3
Joined: September 28th, 2014, 1:31 pm

Post Posted September 28th, 2014, 2:44 pm

As a beginner in Javascript, i was quite in shock to find out that there isn't any "wait" mechanism in javascript (i'm not considering timeout, you'll see why in a second), and if i want to deal with an asynchronous command i needed to use a callback.
the problem begin when you have to force a synchronous order to a sequence of asynchronous command.
the mechanism of callbacks quickly turned for me to a chain of ugly callbacks that made my code much harder to read.
for example:


Code: Select all
//the callbacks technique:
function foo(){
doSomethingAsnyc(value, callback);
}
callback(bar){
doNextAsyncCommand(bar, anotherCallback);
}
 
anotherCallback(bar2){
//and so on...
}




this technique actually breaks down the whole "tree like" structure of the program and forces me to break a logical high level function into a few little functions. its like turning the tree into a pile of leaves.
what i would like to do is to be able to write something like this:

Code: Select all
function foo(){
bar=doSomethingAsync(value);//wait without blocking;
doNextAsyncCommand(bar);//wait; without blocking;
//and so on...

}



this is how things look like in most other languages, but as we already know, in JavaScript it is more problematic because JavaScript is a single threaded language.
there are some smart way to work around things like using a "state machine like" mechanism and promises...but none of them is simple as just waiting for the asynchronous call to return.
and now for my question:
why not using the already exist mechanism of closure to introduce a new none-blocking "wait" feature into javascript??
what i mean is that if you'll think about it, all we need is to insert a new syntax that will cause the javascript interpreter to use the next line as an anonymous handler for the current asynchronous call, just like "function" label tells the interpreter to consider the next line as the body of a function (not exactly, but you know what i mean). like this:

Code: Select all
function foo(){
//wait is a new syntax proposal that will tell the interpreter to wait for the //asynchronous call to finish. behind the scenes "wait" could be implemented by //telling the interpreter to use the next line as the handler of this call,
//and use the function scope as the closure to this "fake" handler.
//we also need to save tell the interpreter to save the current stack.

wait bar=doSomethingAsnyc(value);   
doNextAsyncCommend(bar);                                 
}     


another example:
Code: Select all
function foo(){
var result = "error";
var key=getKey();
if(verify(key)){
        var name=getName();
        if (verify(name)) {
              login(key,name);
              result = "ok";
         }
}
return(result);
}

now lets say that getKey and getName both need to wait to an event to happen so they asking for a callback.
and let us say that getName is meaningless without getting the key first...so we need to put it in the callback to wait.
this will force us to break the function and chain the callbacks like this:
Code: Select all
function foo(){
getKey(callback);
}
 
function callback(key){
if verify(key){
getName(callback2);
}
 
function callback2(name){
if verify(name){
      return "ok";
}
}


but this is ugly!
why couldn't we just do something like this:
Code: Select all
function foo(){
var result = "error";
wait var key=getKey();
if(verify(key)){
    wait var name=getName();
    if (verify(name)) {
        login(key,name);
        result = "ok";
     }
}
return(result);
}


now lets imagine that behind the scenes the wait syntax is doing exactly the same as the chained callbacks...
isn't it great?

so my questions:
1. what do you think about this proposal?
2. is it possible to implement it using only existing mechanism of the current js interpreter features?
let my clarify just one thing:
I'm not suggesting to make JS a multi-threaded language or something fancy..actually i don't want to change anything in the inner-working of JS. I'm trying to suggest a syntactic sugar only and i want to understand if it is possible to introduce it using only existing mechanisms.


do someone here actually knows well how the interpreter of FireFox handles the stack and if it is possible to introduce this kind of syntax exploiting already existing mechanisms?
i can think of few way to implement this with closures like mechanism but i need a better understanding of the stack handling first...
so what do you think???

update:
after posting the same question on another site, things where quickly escalated to a H-U-G-E misunderstanding of my intentions, so let me give another last clarification:
Right now, if i wanted so, i could easily build a "compiler", or more exactly a pre-processor, that would run over my code and would turn it from this:
Code: Select all
function foo(){
var result = "error";
wait var key=getKey();
if(verify(key)){
    wait var name=getName();
    if (verify(name)) {
        login(key,name);
        result = "ok";
     }
}
return(result);
}


into this:

Code: Select all
function foo(){
getKey(callback);
}
 
function callback(key){
if verify(key){
getName(callback2);
}
 
function callback2(name){
if verify(name){
      return "ok";
}
}


now all i am saying is that instead of using external pre-processor, why not just teaching the FireFox interpreter to do it on its own???
hope that my intention are clearer now;)
Last edited by yno1 on September 28th, 2014, 3:33 pm, edited 3 times in total.

LoudNoise
New Member

User avatar
 
Posts: 40048
Joined: October 18th, 2007, 1:45 pm
Location: Next door to the west

Post Posted September 28th, 2014, 2:49 pm

Moving to Web Development
Post wrangler
"Choose between the Food Select Feature or other Functions. If no food or function is chosen, Toast is the default."

yno1
 
Posts: 3
Joined: September 28th, 2014, 1:31 pm

Post Posted September 28th, 2014, 2:54 pm

tnx, and here is a kind of a blind proposal depends on how the interpreter handles the stack:
1. when you see the word "wait" in the beginning of the line, run the command (in our example the call to doSomethingAsnyc(value)). Behind the scenes, pass within the call a fake callable object so that we will not break any existing syntax while the called function will try to send back the results using: callback(result);
this fake callable will actually save the result on top of the stack when it will be ready.

2. when you get to the next line of code, save a pointer (more like a marker) to the current position in the stack(+1 to save space for the return value of the call). leave the function scope and continue to run.

3. when the fake callable object that we have passed within the call is being called (meaning that the call has been completed), jump the stack pointer to the marker and save the return the stack (we saved some space for it remember??).

4. pop the return value into the variable that was after the wait (the "bar"), and continue to run until the end of the function scope.

5. when reaching the end of the function scope, use the same mechanism that already exist in js to finish handling of an event and continue from the same spot where we left.

Frenzie

User avatar
 
Posts: 2135
Joined: May 5th, 2004, 10:40 am
Location: Belgium

Post Posted September 29th, 2014, 7:00 am

I don't understand your intentions. Javascript is primarily event-driven, so I'll just drop these hopefully relevant links.

https://developer.mozilla.org/en-US/doc ... ing_events
https://developer.mozilla.org/en/docs/W ... eb_workers
Intelligent alien life does exist, otherwise they would have contacted us.

yno1
 
Posts: 3
Joined: September 28th, 2014, 1:31 pm

Post Posted October 1st, 2014, 9:09 am

ill try again:
let us say that you want to get a key, and then using that key to get a name. let us also say that you have an API to use that contains getKey() and getName() and they are both takes a callback..
so to get the name we need to call to get key with a callback and then inside the callback we will call to get name...just like this:
Code: Select all
getKey(callback);

function callback(key){
getName(key, callback2);
}

function callback2(name){
//print: we got the name!!
}


but what if i told you that you also need to get the nick name of the user and you can do this only after you have the name? in the API you see the function getNickName() that is also ask for a callback.
we need to do something like this:
Code: Select all
getKey(callback);

function callback(key){
getName(key, callback2);
}

function callback2(name){
getNickname(name, callback3)
}

function callback3(nickname){
//print: we got the nickname!!
}



this looks fine, but here you only have three calls that depend on each other, what will you do if you had 20 or so many calls??
do you have any suggestion of how can we implement this without creating 20 function (one for each call)??

Dom1953
 
Posts: 52
Joined: July 24th, 2014, 6:02 am
Location: Australia

Post Posted November 15th, 2014, 3:21 pm

Interestingly, similar methodology to what you are suggesting is already available in Firefox, Chrome, Opera and proposed in ECMA6: using function* to create a generator function which is executed once to create or "generate" a function to call into the code body.

The generated calling function can be called multiple times and returns when code in the supplied function body executes a return, yield or yield* statement. The simple idea is to write code which initiate a whole lot of dependent steps in order, but executes a yield statement after each initiation. The independent steps must still call back when they have finished (no change here), but every call back can be to the same generated function.

It's quite a clever scenario really: the return or yield statements reduce stack usage of the generator function body to zero, so the stack can expand and collapse between calls into it without creating memory leaks or stack conflict, and each call back resumes after the most recent yield.

Note well, of course, this technology is not known to be supported in IE or Safari.

Return to Web Development / Standards Evangelism


Who is online

Users browsing this forum: No registered users and 2 guests