Javascript Lazy Evaluation Country Game Hints Tutorial

Javascript Lazy Evaluation Country Game Hints Tutorial

Javascript Lazy Evaluation Country Game Hints Tutorial

Ideally, yesterday’s Javascript Lazy Evaluation Country In the Hour Game Tutorial suits …

  • geography buffs … all the way through to …
  • geography students

… alike. Or at least we’d like to help this be so, and in that respect we decided to offer two modes of Hints for the Country Game (whether that be Capitals Game or In the Hour Game) play …

  • show country flags (ie. those “combination emojis” for the country flags, derivable from that country’s ISO 2 letter country code) …

    var useflags=location.search.split('flags=')[1] ? true : false;
    useflags=location.search.split('wimgs=')[1] ? true : useflags;

    function checkflags(cbo, cbochecked) {
    if (cbochecked || document.getElementById('wimgs').checked) {
    useflags=true;
    } else {
    useflags=false;
    }
    applyhints('');
    }

    function orflag(thiscc) {
    var ccchar='', ccsuff='';
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468','127469','127470','127471','127472','127473','127474','127475','127476','127477','127478','127479','127480','127481','127482','127483','127484','127485','127486','127487'];
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(eval('' + dri[eval('' + lri.indexOf(ccchar))])); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    }
    return ccsuff;
    }


    function applyhints(towhat) {
    var yt='', nnyt='';
    if (useflags) {
    if (document.getElementById('flags').checked) {
    myflag=orflag(ccodes[eval(-1 + answer)]);
    document.getElementById('source').style.backgroundImage='URL("' + svgtemp.replace('48','96').replace('30%','49%').replace('>1 +', '>' + myflag) + '")';
    document.getElementById('source').style.backgroundPosition='right center';
    document.getElementById('source').style.backgroundRepeat='no-repeat';
    }
    if (document.getElementById('wimgs').checked) {
    if (yourtzlist.indexOf(',' + ccodes[eval(-1 + answer)] + ',') != -1) {
    yt=yourtzlist.split(',' + ccodes[eval(-1 + answer)] + ',')[1].split('>')[1].split('<')[0];
    nnyt=yt.replace(yt.split('/')[0] + '/','');
    //alert(document.getElementById('tzi').src.split('?')[0].split('#')[0] + '?tzexact=' + encodeURIComponent(yt.replace(/\ /g,'_')) + '&tznickname=' + encodeURIComponent( nnyt.replace(/\ /g,'_') ));
    document.getElementById('tzi').src=document.getElementById('tzi').src.split('?')[0].split('#')[0] + '?tzexact=' + encodeURIComponent(yt.replace(/\ /g,'_')) + '&tznickname=' + encodeURIComponent( nnyt.replace(/\ /g,'_') );
    }
    }
    } else {
    document.getElementById('source').style.backgroundImage='';
    document.getElementById('source').style.backgroundRepeat='no-repeat';
    document.getElementById('ourcanvas').style.backgroundImage='';
    document.getElementById('ourcanvas').style.backgroundRepeat='no-repeat';
    }
    return towhat;
    }

    …and/or …
  • Wikipedia images …

    function checkwimgs(cbo, cbochecked) {
    if (cbochecked || document.getElementById('flags').checked) {
    useflags=true;
    } else {
    useflags=false;
    }
    applyhints('');
    }

    function fgcit(iois) {
    var outof=["left top","left center","left bottom","right top","right center","right bottom","center top","center center","center bottom"];
    var startwith='', endwith='', imglist=[];
    if (iois != null) {
    if (iois.src.indexOf('tzexact=') != -1) {
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.body.outerHTML.replace(/\"\;/g,"'").indexOf("document.getElementById('ourcanvas').style.background") != -1) {
    //document.getElementById('ourcanvas').style.backgroundRepeat='no-repeat';
    startwith="document.getElementById['ourcanvas'].style.background" + aconto.body.outerHTML.replace(/\&\;/g,"&").replace(/\"\;/g,"'").split("document.getElementById('ourcanvas').style.background")[1].split(';')[0] + ';';
    imglist=startwith.split(',');
    for (var jiu=0; jiu<imglist.length; jiu++) {
    if (jiu == 0) {
    endwith=imglist[jiu].trim().replace(/\)/g, ') ' + outof[0] + ' no-repeat').replace('URL(', 'linear-gradient(rgba(255,255,255,0.7),rgba(255,255,255,0.7)),URL(');
    } else {
    endwith+=',' + imglist[jiu].replace(')', ') ' + outof[eval(jiu % outof.length)] + ' no-repeat')
    }
    }
    eval(endwith.replace("document.getElementById['ourcanvas'].", "document.getElementById('ourcanvas')."));
    }
    }
    }
    }
    }
    }

After all, most of us are not destined to visit or travel or tour all these countries, alas!

And so, again, hope you try the changed gradual_reveal_country_game.html‘s Country Capital and/or In the Hour Game web application, below too, yourself?!


Previous relevant Javascript Lazy Evaluation Country In the Hour Game Tutorial is shown below.

Javascript Lazy Evaluation Country In the Hour Game Tutorial

Javascript Lazy Evaluation Country In the Hour Game Tutorial

The “genericization drive” regarding “country map iframe Geo Chart content” has passed us now, as last discussed in yesterday’s Javascript Lazy Evaluation Country Capital Game Context Tutorial, about our …

  • Country Capital Game … and today we start down the road to other game types that could involve “country map iframe Geo Chart content” and came up with a …
  • Country “In the Hour” Game

… whereby a user matches …

  • a “draggable” source time in some country … with …
  • a “droppable intoabletarget “country map iframe Geo Chart content” table cell

… the correct selection of which scores for the game player. You could think of it as a TimeZone Game, perhaps?!

The PHP TimeZone smarts helped derive the huge Javascript variable we now define in the game, and used


var ud = new Date();
var uhour = ud.getUTCHours();
var umin = ud.getUTCMinutes();
var chours=[], cinthehours=[], sofarhrs=' ';



var yourtzlist="<option value=\"GMT\" data-geo=\"51.4934,0.0098,GMT,GB,+0\">GMT</option><option value=\"Africa/Abidjan\" data-geo=\"5.31666,-4.03334,GMT,CI,+0\">Africa/Abidjan</option><option value=\"Africa/Accra\" data-geo=\"5.55,-0.21667,GMT,GH,+0\">Africa/Accra</option><option value=\"Africa/Addis_Ababa\" data-geo=\"9.03333,38.7,EAT,ET,+3\">Africa/Addis_Ababa</option><option value=\"Africa/Algiers\" data-geo=\"36.78333,3.05,CET,DZ,+1\">Africa/Algiers</option>"; // etcetera etcetera etcetera

function choosejusttheone(thes, thiscc) {
if (!thes) { return false; }
if (eval('' + yourtzlist.split(',' + thiscc + ',').length) != 2) { return true; }
if (yourtzlist.split(',' + thiscc + ',')[1].split('"')[0].indexOf('.') != -1) { return true; }
if (sofarhrs.indexOf(' ' + yourtzlist.split(',' + thiscc + ',')[1].split('"')[0] + ' ') != -1) { return true; }
return false;
}


function getnextcountrycode() {
if (eval('' + ccodes.length) < 9) {
var mycc=document.getElementById('myctable').innerHTML;
var opts=document.getElementsByTagName('option');
var ths=document.getElementsByTagName('th');
var atry=Math.floor(Math.random() * eval('' + opts.length));
while (optfinds.indexOf(' ' + opts[eval('' + atry)].value + ' ') != -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + opts.length));
}
while (mycc.indexOf('>' + opts[eval('' + atry)].innerText + '<') == -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + opts.length));
if (mycc.indexOf('>' + opts[eval('' + atry)].innerText + '<') != -1) {
while (optfinds.indexOf(' ' + opts[eval('' + atry)].value + ' ') != -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + opts.length));
}
}
}
optfinds+=opts[eval('' + atry)].value + ' ';
ccodes.push(opts[eval('' + atry)].value);
cnames.push(opts[eval('' + atry)].innerText);
ccapitals.push(mycc.split("<th>" + opts[eval('' + atry)].innerText + "</th><th>")[1].split("<")[0]);
if (!simple) {
chours.push(-99);
cinthehours.push("");
} else {
sofarhrs+=yourtzlist.split(',' + opts[eval('' + atry)].value + ',')[1].split('"')[0] + ' ';
cinthehours.push(('0' + eval(eval(eval(eval(yourtzlist.split(',' + opts[eval('' + atry)].value + ',')[1].split('"')[0].replace('+','')) + uhour) + 24) % 24)).slice(-2) + ':' + ('0' + umin).slice(-2));
}

}
}

… as required. The user can toggle between the two game modes by clicking that top button.

We, again, hope you try the changed gradual_reveal_country_game.html‘s Country Capital and In the Hour Game web application, below too, yourself?!

Stop Press

We wanted to start involving Wikipedia links and update Geo Charts in either mode of play for the games above, and as a result “function getnextcountrycode” became …


function getnextcountrycode() {
if (eval('' + ccodes.length) < 9) {
var mycc=document.getElementById('myctable').innerHTML;
var opts=document.getElementsByTagName('option'), longis='', latis='';
var ths=document.getElementsByTagName('th');
if (optslength < 0) {
for (iii=0; iii<opts.length; iii++) {
if (('' + opts[iii].value).indexOf(',') != -1 && optslength < 0) { optslength=eval(-1 + iii); }
}
if (optslength < 0) { optslength=eval('' + opts.length); }
}
var atry=Math.floor(Math.random() * eval('' + optslength));
while (optfinds.indexOf(' ' + opts[eval('' + atry)].value + ' ') != -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + opts.length));
}
while (mycc.indexOf('<th>' + opts[eval('' + atry)].innerText + '</th><th>') == -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + optslength));
if (mycc.indexOf('<th>' + opts[eval('' + atry)].innerText + '</th><th>') != -1) {
while (optfinds.indexOf(' ' + opts[eval('' + atry)].value + ' ') != -1 || opts[eval('' + atry)].value == 'MK' || choosejusttheone(simple, opts[eval('' + atry)].value)) {
atry=Math.floor(Math.random() * eval('' + optslength));
}
}
}
optfinds+=opts[eval('' + atry)].value + ' ';
ccodes.push(opts[eval('' + atry)].value);
cnames.push(opts[eval('' + atry)].innerText);
ccapitals.push(mycc.split("<th>" + opts[eval('' + atry)].innerText + "</th><th>")[1].split("<")[0]);
subfroms.push('[-89.0000|-88.0000|~From~,2]');
if (!simple) {
if (document.getElementById(ccapitals[eval(-1 + ccapitals.length)].replace(/\_/g,'%20').replace(/\ /g,'%20'))) {
longis='' + document.getElementById(ccapitals[eval(-1 + ccapitals.length)].replace(/\_/g,'%20').replace(/\ /g,'%20')).value.split(',')[0].split('|')[0];
latis='' + document.getElementById(ccapitals[eval(-1 + ccapitals.length)].replace(/\_/g,'%20').replace(/\ /g,'%20')).value.substring(eval(1 + eval('' + longis.length)));
cplaces.push(latis + '|' + longis);
subtos.push('[' + cplaces[eval(-1 + cplaces.length)] + '|~' + ccapitals[eval(-1 + ccapitals.length)].replace(/\_/g,'%20') + '~,2]');
} else {
cplaces.push('');
subtos.push('[-89.0000|-88.0000|~From~,2]');
}
chours.push(-99);
cinthehours.push("");
} else {
sofarhrs+=yourtzlist.split(',' + opts[eval('' + atry)].value + ',')[1].split('"')[0] + ' ';
cinthehours.push(('0' + eval(eval(eval(eval(yourtzlist.split(',' + opts[eval('' + atry)].value + ',')[1].split('"')[0].replace('+','')) + uhour) + 24) % 24)).slice(-2) + ':' + ('0' + umin).slice(-2));
subtos.push(lastsubtos);
cplaces.push(decodeURIComponent(lastsubtos.split('~')[1]));
}
}
}


Previous relevant Javascript Lazy Evaluation Country Capital Game Context Tutorial is shown below.

Javascript Lazy Evaluation Country Capital Game Context Tutorial

Javascript Lazy Evaluation Country Capital Game Context Tutorial

The improvements, today, onto yesterday’s Javascript Lazy Evaluation Country Capital Game Tutorial‘s “Country Capital Game” web application revolve around “context” …

  • there’s the “context” between land masses and sea … as well as …
  • there’s the “context” between country and world view

… both of which take us further into the realms of Google Chart Geo Chart usage, even “unique usage for us”, as far as the first one above.

Regarding the “context” between land masses and sea, wouldn’t it be good, on the map to colour the land with a greener tinge? Anyone, anyone, is green the go? Yes, 3GPP, or is that CP3O, disguised as R2D2 … anyway … yes, we could …

  • isolate the inherent map contents in its SVG guise … but if we could just censure the content here just that teensy weensy bit, now
  • we could torture that SVG to reveal its fill colourwe could do research and development, via a web browser web inspector, into that SVG’s path element fill colour … spoiler alert … #f5f5f5 (grey) … and …
  • liquidate its assetsgently coerce the map into thinking its SVG path element fill colour should be #c5f5f5 (our greenish tinge)

Thanks, can I call you 3o?


function hashit(iois) {
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
aconto.getElementById('myh').style.display='none'; // aconto.getElementById('chart_div').scrollIntoView();
// Thanks to https://stackoverflow.com/questions/6088409/svg-drop-shadow-using-css3
setTimeout(function(){ aconto.getElementById('chart_div').innerHTML=aconto.getElementById('chart_div').innerHTML.replace('</svg>', '</svg><style> .shadow { -webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); } </style>').replace(/\#f5f5f5\;\"/g,'#c5f5f5;" class="shadow"').replace(/\#f5f5f5\"/g,'#c5f5f5" class="shadow"'); }, 4000);
}
}
}
}

Oh, okay then. Sorry. Thanks, 3GPPsubsection III! You do get straight to the point, there!

And then, regarding the “context” between country and world view, we have a two part improvement to matters here, we feel. Firstly, we hope to help contextualize “where in the world” is a country, and secondly, we wanted to “value add” for these popup windows we might open as the user hovers over a “country map” cell (filled with iframe Google Chart Geo Chart content), otherwise such interventions can be annoying, and we hope we’re not making the game too easy by adding to …

  • the existant onmouseover event creating popup window … now …
  • identical #c5f5f5 filled land mass “country map” … our newly added …
  • “world map” view of that same country, highlighted

for context


var wmapurl='<iframe src="//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=World%20Map&width=834&height=520&country=Country&popularity=Popularity&data=%20[~IT~,2]"></iframe>';

var subfrom='~IT~';
var subto='~IT~';

function woit(thissrc,thiso) {
if (thissrc.indexOf(hastoinvolve.replace(' src=','//')) != -1 && thissrc.replace('http:','').replace('https:','') != lastwosrc.replace('http:','').replace('https:','') && sowoa.replace(/http\:/g,'').replace(/https\:/g,'').indexOf(' ' + thissrc.replace('http:','').replace('https:','') + ' ') == -1) {
lastwosrc=thissrc;
var therect=thiso.getBoundingClientRect();
if (wo) {
if (!wo.closed) {
wo.close();
}
wo=null;
sowoa+=thissrc + ' ';
subto='~' + thissrc.split('?title=')[1].split(';')[0] + '~';
wo=window.open(thissrc,'_blank','top=' + therect.top + ',left=' + therect.left + ',width=' + eval(2 * thewidth) + ',height=' + eval(2 * theheight));
//wo.focus();
wo.onload = function() {
setTimeout(function(){ wo.document.getElementById('chart_div').innerHTML=wo.document.getElementById('chart_div').innerHTML.replace('</svg>', '</svg><style> .shadow { -webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); } </style>').replace(/\#f5f5f5\;\"/g,'#c5f5f5;" class="shadow"').replace(/\#f5f5f5\"/g,'#c5f5f5" class="shadow"'); wo.document.getElementById('chart_div').innerHTML+=wmapurl.replace(subfrom,subto); }, 4000);
};

} else {
sowoa+=thissrc + ' ';
subto='~' + thissrc.split('?title=')[1].split(';')[0] + '~';
wo=window.open(thissrc,'_blank','top=' + therect.top + ',left=' + therect.left + ',width=' + eval(2 * thewidth) + ',height=' + eval(2 * theheight));
//wo.focus();
wo.onload = function() {
setTimeout(function(){ wo.document.getElementById('chart_div').innerHTML=wo.document.getElementById('chart_div').innerHTML.replace('</svg>', '</svg><style> .shadow { -webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7)); } </style>').replace(/\#f5f5f5\;\"/g,'#c5f5f5;" class="shadow"').replace(/\#f5f5f5\"/g,'#c5f5f5" class="shadow"'); wo.document.getElementById('chart_div').innerHTML+=wmapurl.replace(subfrom,subto); }, 4000);
};

}
}
}

… where element chart_div represents all the Google Chart Geo Chart smarts, thanks!

We hope you try the changed gradual_reveal_country_game.html‘s Country Capital Game web application, below too, yourself?!


Previous relevant Javascript Lazy Evaluation Country Capital Game Tutorial is shown below.

Javascript Lazy Evaluation Country Capital Game Tutorial

Javascript Lazy Evaluation Country Capital Game Tutorial

Just like with yesterday’s Javascript Lazy Evaluation Game Involvement Tutorial

… of recent times. But this time, with our gradual_reveal_country_game.html Drag and Drop Country Capital Game we introduce to the target “Drop Zone” table cell content, for the first time, we have …

… to match the associated source “Drag” element available for the user to drag and drop into the correct table cell below, to score in today’s geography game.


Previous relevant Javascript Lazy Evaluation Game Involvement Tutorial is shown below.

Javascript Lazy Evaluation Game Involvement Tutorial

Javascript Lazy Evaluation Game Involvement Tutorial

Yes, we’ve decided to involve the Lazy Evaluation and async and await and Promise and setTimeout Javascript logic of yesterday’s Javascript Lazy Evaluation Promise Tutorial into a Drag and Drop mathematics game for Small Integers from 1 to 9. Can you hear Alice in the middle room?!

Our “mathematical sentences” to solve in this game, where the operators can be + or – or / or * or %, and integer is number from 1 to 9, can be …

  • hard … made up of …
    integer operator integer operator integer operator
    integer operator integer operator
    integer operator
    integer operator integer operator integer

    … or …

  • simple … made up of …
    integer operator integer
    operator integer
    operator
    integer operator integer

… parts to the “mathematical sentence” revealed gradually, using those aforesaid mentioned Javascript techniques, the less revealed as the user answers, the bigger the score, if correct.

The (non-mobile only) cursor and cell background images are formed via data URI svg+xml formats …

Cursor Cell

<style>
* {
cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='48' width='126' viewport='0 0 100 100'><polyline points='40,2 20,15 80,10 60,20 126,30 86,48' style='fill:none;stroke:black;stroke-width:3' /><text y='90%'>\002753</text><ellipse cx='24' cy='20' rx='22' ry='13' style='fill:purple' /><ellipse cx='22' cy='17' rx='19' ry='12' style='fill:lime' /><ellipse cx='21' cy='14' rx='16' ry='12' style='fill:yellow' /><rect x='40' y='20' width='80' height='25' style='fill:blue'><animate attributeType='CSS' attributeName='opacity' from='1' to='0' dur='5s' repeatCount='indefinite' /></rect>Sorry, your browser does not support inline SVG.</svg>") 16 16, crosshair;
}
</style>

var svgtemp="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='48' width='126' viewport='0 0 100 100'><text x='20%' y='30%' stroke='blue'>1 +</text></svg>";
// ... used later regarding tdsos = document.getElementsByTagName('td'); // ... and nextanswer is ... next answer ...
setTimeout(() => { tdsos[eval(-1 + nextanswer)].style.backgroundImage='URL("' + svgtemp.replace('>1 +', '>' + parts[eval(-1 + nextanswer)].trim()) + '")'; getnextanswer(); }, 200);

… in our gradual_reveal_game.html Small Integer Game you can also try below …


Previous relevant Javascript Lazy Evaluation Promise Tutorial is shown below.

Javascript Lazy Evaluation Promise Tutorial

Javascript Lazy Evaluation Promise Tutorial

Working on yesterday’s Javascript Lazy Evaluation Follow Up Tutorial subject matter further today, we’d like to introduce a glossary of terms for beginners here …

  • async
    function

    The async function declaration creates a binding of a new async function to a given name. The await keyword is permitted within the function body, enabling asynchronous, promise-based behavior to be written in a cleaner style and avoiding the need to explicitly configure promise chains.

  • await
    operator

    The await operator is used to wait for a Promise and get its fulfillment value. It can only be used inside an async function or at the top level of a module.

  • Promise
    object (thenable)

    The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

  • Lazy
    syntax (function)

    Lazy evaluation means to delay the evaluation of an expression until it’s needed. Lazy evaluation is sometimes referred to as call-by-need.

    The opposite of lazy evaluation is an eager evaluation. It’s an evaluation strategy used in most programming languages.

    Lazy evaluation makes it possible to:

    define potentially infinite data structures
    increase performance by avoiding needless computations
    customize iteration behavior for data structures that want its elements accessible to the public

  • setTimeout
    function (global)

    The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

Meanwhile you can (re-)try our Javascript modified lazy_async.htm web application in a new tab or below …


Previous relevant Javascript Lazy Evaluation Follow Up Tutorial is shown below.

Javascript Lazy Evaluation Follow Up Tutorial

Javascript Lazy Evaluation Follow Up Tutorial

Further to yesterday’s Javascript Lazy Evaluation Primer Tutorial‘s subject matter regarding Lazy Evaluations and Javascript async functions, we’ve stumbled upon another great resource, thanks, from which we can base, to develop a web application, we’re hoping.

Within this “proof of concept” code basis you will find setTimeout (timer) references to Lazy Evaluations like …


setTimeout(() => {
aminterested='Just';
resolve("fast");
consolelog("fast promise is done");
aminterested='';
}, 1000);

… as a function that …

  • attempts to start in one second’s time …
  • as needed that function is performed

The possibilities here are multifaceted, and varied, and definitely worth experimenting with, within Javascript client work.

So our starting web application can be tried in a new tab or below …


Previous relevant Javascript Lazy Evaluation Primer Tutorial is shown below.

Javascript Lazy Evaluation Primer Tutorial

Javascript Lazy Evaluation Primer Tutorial

Do you remember, with the presentation of …

  • Promise Object Sleeping and Doing Primer Tutorial we talked about the Javascript Promise object? Well today, in that similar line of thinking, we wanted to touch on …
  • Lazy Evaluation in Javascript …

    Lazy evaluation means to delay the evaluation of an expression until it’s needed. Lazy evaluation is sometimes referred to as call-by-need.

    The opposite of lazy evaluation is an eager evaluation. It’s an evaluation strategy used in most programming languages.

    Lazy evaluation makes it possible to:

    define potentially infinite data structures
    increase performance by avoiding needless computations
    customize iteration behavior for data structures that want its elements accessible to the public

Personally, we’re more your “eager” types, but we’ve had help in the past from brilliant “lazy” types too, especially when we presented Selection API and Clipboard API Tutorial, and so, we honed in on some Javascript “Lazy Evaluation” code, and put together some status information shown regarding timings and calls with respect to Javascript …

  • “Lazy Evaluation” in Javascript … classical syntax goes …

    f = () => expression;

    … and …
  • async function in Javascript … classical syntax example goes …

    function resolveAfter2Seconds() {
    return new Promise((resolve) => {
    setTimeout(() => {
    resolve('resolved');
    }, 2000);
    });
    }

    async function asyncCall() {
    console.log('calling');
    const result = await resolveAfter2Seconds();
    console.log(result);
    // Expected output: "resolved"
    }

… into the changed clipboard_api_test.html Selection and Clipboard API usage web application for you to try yourself with some image or text clipboard usages.


Previous relevant Promise Object Sleeping and Doing Primer Tutorial is shown below.

Promise Object Sleeping and Doing Primer Tutorial

Promise Object Sleeping and Doing Primer Tutorial

We’re here today to fulfil yesterday’s Web Application Controlled Progress Cursor Primer Tutorial‘s pledge …

… which reminded me that we need to learn some more about the promise object

… and were happy to discover the Promise object talents of …

  • sleeping … allowing for …
  • multitasking
  • doing … all using clientside Javascript

… very interesting. The serverside languages such as PHP make it a doddle to multitask (via sleep) but Javascript sleep has not always been a straightforward proposition, until we could promise, that is!

Today’s await.html‘s use of it to sleep and in between show …

  1. analogue clock … and …
  2. Dams of the USA (via dams_usa.html changed this way)

… asynchronously both doing their own thing while the await.html works away in the background too, feeding off “child 2” clicks of “child 1” above to know when to say how long the dams took to load. Yes, the “child 2” “onload” event, alone, cannot help determine this, but more “drilling into” the inner workings of the code behind “child 2″‘s progress element, via …


<html>
<head>
<script type='text/javascript'>
var numsleeps=700000;
var ix=0;
var d=new Date();
var marks=[new Date(), new Date()];
var imark=0;

function sleep(ms) { // thanks to https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
console.log(numsleeps + ' Taking a break...' + d);
await sleep(2000);
d=new Date();
console.log(numsleeps + ' Two seconds later, showing sleep in a loop...' + d);

// Sleep in loop
for (let i = 0; i < 5; i++) {
if (i === 3) {
await sleep(2000);
d=new Date();
console.log(numsleeps + ' ' + d);


}
}
numsleeps--;
if (('' + numsleeps) != '0' && ('' + numsleeps).indexOf('-') == -1) { setTimeout(demo, 1); }
}

function betw() {
var seconds = (marks[1].getTime() - marks[0].getTime()) / 1000;
document.getElementById('sh1').innerHTML='It took ' + seconds + ' seconds (from ' + marks[0] + ' to ' + marks[1] + ') to load the dams.';
numsleeps=0;
}

function markit() {
marks[imark]=d;
imark++;
console.log('mark ' + imark + ': ' + d);
if (imark == 2) { setTimeout(betw, 800); imark=0; }
}

demo();
</script>
</head>
<body>
<h1>Sleeping and Doing via Promise Object - RJM Programming - July, 2021 <span id=sh1></span></h1>
<table style=width:100%;height:90%;><tr><td><iframe onclick="markit();" id=lif src=./analogue_clock.htm style=width:100%;height:100%;></iframe></td><td><iframe id=rif src=./dams_usa.html?rand=7564675 style=width:100%;height:100%;></iframe></td></tr>
</body>
</html>


Previous relevant Web Application Controlled Progress Cursor Primer Tutorial is shown below.

Web Application Controlled Progress Cursor Primer Tutorial

Web Application Controlled Progress Cursor Primer Tutorial

We had occasion to revisit the card game (and more) recent web application exploits highlighted in the recent Just Javascript Card Game Cursor Tutorial thread of blog postings and shaped to play Bridge via …


https://www.rjmprogramming.com.au/HTMLCSS/cards_usefocus.html?card_memories=04.1:ara

… and was “personally relatively” happy up to the first Javascript prompt popup window. Huh?! What’s with “personally relatively”? Can I be serious? Well, I’m insulted!

The thing is, I don’t mind, when I’m writing the code (funny about that?!) very complex and convoluted prompt window instructions and options. But …

  • not everybody is willing to read such long diatribes
  • actions can speak louder than words, so we figure between those first two prompt windows in a Bridge or 500 card game, it would be beneficial to show a “progress cursor” (ie. usually associated with the user waiting for a process to finish) between the first and second prompt windows to help show the players there could be waiting and irrelevant players turning away should all four players want to play fairly in their game

It was an interesting Javascript coding exercise …

  1. (sort of) overload the “prompt” function with our inhouse “superprompt” function via …
    • globally replace ” prompt(” with ” superprompt(“
    • globally replace “=prompt(” with “=superprompt(“
  2. add the following Javascript code …

    var aheadoffirst=(('' + document.URL.replace('?', '&').indexOf('&card_') != -1) ? trueize() : 0);

    function dbcpp() {
    if (aheadoffirst == 2) {
    document.body.style.cursor='progress'; // between first and second prompt windows
    setTimeout(dbcpp, 1000);
    } else if (aheadoffirst == 0) {
    document.body.style.cursor='pointer';
    } else {
    document.body.style.cursor='pointer';
    setTimeout(dbcpp, 1000);
    }
    }

    function trueize() { // bit like a promise
    setTimeout(dbcpp, 1000);
    return 1;
    }


    function superprompt(opone, optwo) {
    if (aheadoffirst == 3) {
    document.body.style.cursor='pointer';
    aheadoffirst=0;
    } else if (aheadoffirst != 0) {
    aheadoffirst++;
    if (aheadoffirst == 3) {
    document.body.style.cursor='progress'; // between first and second prompt windows
    }
    }
    return prompt(opone, optwo);
    }

… which reminded me that we need to learn some more about the promise object.

See this in action with the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in eLearning, Event-Driven Programming, Games, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *