I'm having major trouble getting my app to behave while loading. I don't think it is very fair to users to allow them access to the app until it's finished loading and is ready / responsive.
Please note: every thing else works fine in my app I just can't get functions to run in order.
function LOADINGapp(){
//app loads but allows user to enter before loading is finished
$.when(getToday()).then(reorderdivs()).then(getSomething()).then(setupSomethingElse()).then(loadAnotherSomething()).then(INITapp());
//app stops dead at getToday but (Crome javascript console) no errors
getToday(function(){reorderdivs(function(){getSomething(function(){setupSomethingElse(function(){loadAnotherSomething(function(){INITapp();});});});});});
//app loads but allows user to enter before loading is finished
getToday(reorderdivs(),getSomething(),setupSomethingElse(),loadAnotherSomething(),INITapp());
//getToday();
//reorderdivs();
//getSomething();
//setupSomethingElse();
//loadAnotherSomething();
//INITapp();
}
function INITapp(){
$('#SPLASH').hide();
}
Can someone please assist me, I don't understand. Done and doing a tone of research to get this to behave.
Thanks
I haven't used when/then from jquery before, but it looks like you need to pass the pointers to the methods. Right now you are actually executing them all at once. Try:
$.when(getToday())
.then(reorderdivs)
.then(getSomething)
.then(setupSomethingElse)
.then(loadAnotherSomething)
.then(INITapp);
(Notice the missing parentheses)
Also, be aware the only true asynchronous object in JS is an AJAX call. setTimeout is NOT asynchronous, it is a queueing method. Read John Resig's post:
http://ejohn.org/blog/how-javascript-timers-work/
I solved it by jumping (only allowing my LOADINGapp function to do one thing at a time) so it works in stages. once a stage (a function) is complete it jumps back into the LOADINGapp function.
var L=0;
function LOADINGapp(){
if(L==0){getToday();}
else if(L==1){reorderdivs();}
else if(L==2){getSomething();}
else if(L==3){setupSomethingElse();}
else if(L==4){loadAnotherSomething();}
else if(L==5){INITapp();};
}
function INITapp(){
$('#SPLASH').hide();
}
example:
function getSomething(){
//app suff
//app suff
//app suff
L = 3;
LOADINGapp();
}
the only thing I will improve is just do L++; at the end of LOADINGapp as it saves writing it all over the place. PS:thanks for the efforts guys
It is probably something to do with asynchronous functions. So you could try making those functions with a callback, as mentioned here: http://pietschsoft.com/post/2008/02/JavaScript-Function-Tips-and-Tricks.aspx.
Related
I'm trying to debug something live on a customer website and my code is all inside an anonymous function block. I don't know if there's anyway to reach that code to execute functions or look at variables in there. I can't put a breakpoint either because this code is dynamically generated each time the page is refreshed and the breakpoint doesn't stick.
(function() {
var Date = "14 September 2022 14:44:55"; // different every refresh for example
var Holder = {
var Items = {
item1: "Value1",
item2: "Value2"
};
function getItem(name) {
return Items[name];
};
function setItem(name, value) {
Items[name] = value;
};
setTimeout(DoSomething(), 2000);
})();
That's not the actual code, just a bare minimum example to illustrate the problem.
Is there anyway to get reach getItem() or Items?
Without a breakpoint that code probably runs to completion then POOF it's all gone anyway.
Redefine setTimeout
If it really is the case that the code inside the anonymous function calls other browser methods, you might be able to insert a detour at runtime that you can then put a breakpoint on.
For this to work, you will need to be able to inject new code into the page before the anonymous code, because there's no other way to invoke the IIFE.
Your example code uses setTimeout, so here's what I would try to insert:
let realSetTimeout = window.setTimeout
window.setTimeout = (...args) => {
debugger
return realSetTimeout(...args)
}
Lots of unrelated code might be calling setTimeout, in which case this could break the page or just make debugging really tedious. In that case, you might make it only debug if one of the setTimeout args has a value that's used in your example, e.g.:
// only break for our timeout
if(args[1] === 2000) debugger
Something like that might not trigger for only your code, but it would hugely reduce the number of other codepaths that get interrupted on their journey through the commonly-used browser capability.
Alternatively, use Charles Proxy to rewrite the body of the HTML page before it enters your browser. You could manually insert a debugger call directly into the anonymous function. Charles is not free, but I think they have a demo that might let you do this. If you do this professionally, it's probably a good purchase anyway. Your employer might even pay for the license.
If you can't use Charles (or a similar tool), you could instead set up a local proxy server using Node which does the rewrite for you. Something like that might only take an hour to throw together. But that is a bigger task, and deserves its own question if you need help with that.
No unfortunately.
The variables inside of the anonymous object are created in a scope which is inaccessible from the outside.
One of the main benefits of using a closure!
You’ll have to find a way to insert your own code inside of it by modifying the function that is generating those objects. If you can’t do that, then you’ll have to take the fork in the road and find another way.
I have adopted the library Q.js into my program to try and solve some problems with the order of execution in my code, I am new to promises and deferred in general, so this is a pretty difficult step for me.
At this point in time, I am using Q v1 within ASP.NET MVC, and therefore I am using Visual Studio 2013.
Now, the actual code for what I am doing is a great deal longer than this, but I'll attempt to be concise, as I often get told my questions are too long and verbose.
I start by including q.js and require.js normally, nothing special is going on here. It works fine, it compiles, it runs, all is happy and well.
#Scripts.Render("~/scripts/q")
#Scripts.Render("~/scripts/require")
<script type="text/javascript">
Q().then(function(){
// some code executes here.
$.blockUI(); // the whole page is blocked while loading.
console.log("[1] first step. blocking the page.");
}).then(function() {
console.log("[2.1] starting the second step.");
require(['home/app/init'], function(app) {
console.log("[2.2] within the require function.");
new app.init().wiring(); // this does some preliminary stuff for the app
});
console.log("[2.3] outside of the require function.");
}).then(function() {
console.log("[3.1] made it to the third step. stuff happens.");
});
</script>
Now, running this code, the console output for 2.1 and 2.3 are visible before 2.2 - which is the crux of the problem. I want it to run in order. So I dug a bit more, and found this suggestion; changing my require call to look more like this was suggested to me ..
// ....
.then(function(){
var promise = Q.when(require['home/app/init'], function(app) {
console.log("[2.2.1] within the require");
new app.init().wiring();
}).then(function() {
console.log("[2.2.2] I expect to see this after 2.2.1");
});
console.log("[2.3] outside of the require function.");
});
Now I get that 2.3 will still run before 2.2.1, but I'm still seeing 2.2.2 running before 2.2.1 - and I thought that wrapping the behavior in the Q.when(fn) was supposed to fix that?
Can someone help me understand why these are not running in the order I am asking them to?
For a bit more information, the file home/app/init is actually a Typescript file that looks a bit like this;
home/app/init.ts
export class init {
public function wiring() {
// some simple things happening here, nothing special.
}
}
I am not sure if this question qualifies to have the ASP.NET MVC tag, but the fact that I am using that framework is paramount to the tooling I use, which does have influence over what I can do (for instance, I'm having a hard time with things involving node.js because of Visual Studio) - so I am tagging it explicitly to be sure people realize the kind of development environment I am in.
Update
I have made a bit of progress on this, though I am still a bit uncertain. At the moment, the following code seems to run more in the order I am expecting.
// .....
.then(function(){
console.log("[2.1]");
// create a deferred promise
var deferred = Q.defer();
require(['home/app/init'], function(app) {
// we are inside the require function
console.log("[2.2]");
// run the actual method
new app.init().wiring();
// report back to the console.
console.log("[2.3]");
// resolve the promise
deferred.resolve();
});
console.log("[2.4]");
Q.when(deferred.promise).then(function() {
console.log("[2.5]");
}).then(function(){
// ... continue
});
This at least seems to cause the code to pause and wait for the require to finish before it goes on to 2.5, but I'm not sure if this is the correct way to do this with Q.js.
2.1 will run before 2.2 because that's the order you are running the code but the 2.2 code runs asynchronously so gets run once require has got everything in order which will take more time than it takes the 2.3 code to execute
I think in your second block of code you want to move the 2.2.2 block inside the when see the documentation for when at the bottom of this page
https://github.com/kriskowal/q
Is there any existing api/code for handling and chaining long-running "async" javascript functions?
First of all I don't think there are any such thing as an asynch function in js right? I guess the only asynch api is the http-request that jQuery uses or am I wrong?
Anyway, when using jQuery to first for instance ping a server, then login, then load a bunch of items etc, it's not very pretty to wrap these functions in each others completed-handler if you know what I mean.
What I have done now is to define a Task-class with some kind of linked-list capabilities, with a task.next-property etc. When I chain these and execute task.run on the first, I have designed it so that each task is run and when its completed-handler is called it runs the task.next task etc.
This works fine but I'm wondering is there is any existing more complete apis for this allready out there I should use?
Maybee with support for cancellation, progress, exception-aggregation etc?
Maybee there are plans for similar async/wait tasks as there are in C# now, but in js?
If you are targetting the browser, you can use setTimeout.. and break up your code into functions, with each iteraction taking one off the stack/queue, and doing that part.. there are also web workers...
If you are doing server-side JS (such as NodeJS), then there are libraries to make async tasks easier to manage. In the browser it takes work... You'll essentially want to create a bundle of tasks, and work them..
function processBundle(tasks, callback) {
var hnd = setTimeout(doWork, 20);
function doWork() {
var item = tasks.shift();
item();
return (
tasks.length
? setTimeout(doWork, 20)
: callback()
);
}
}
//using it...
var items = [];
items.push(simpleFunction1);
...
items.push(simpleFunctionN);
processBundle(items, function(){
alert("done!");
});
Could someone explain the javascript that makes up Google's Website Optimiser Control script? Specifically: the first two lines, which seem to be empty functions, and why is the third function wrapped parentheses () ?
As far as I can tell this script is basically writing out a new <script> which presumably loads something for A/B testing.
function utmx_section(){}
function utmx(){}
(function() {
var k='0634742331',d=document,l=d.location,c=d.cookie;
function f(n) {
if(c) {
var i=c.indexOf(n+'=');
if (i>-1) {
var j=c.indexOf(';',i);
return escape(c.substring(i+n.length+1,j<0?c.length:j))
}
}
}
var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;
d.write('<sc'+'ript src="'+'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'+'/siteopt.js?v=1&utmxkey='+k+'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='+new Date().valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+'" type="text/javascript" charset="utf-8"></sc'+'ript>')
}
)();
I've attempted to step through with the firebug debugger but it doesn't seem to like it. Any insights much appreciated.
Many thanks
inside anonymous function it shortens names of document and cookies inside it at first, function f(n) gets value of cookie under name n. Then Google reads its cookies and with help of d.write it loads its scripts (as I see they are related to Google Analytic). This way it makes On-Demand JavaScript loading... Actually you load these scripts all the time, Google just needs some additional parameters in url, so this is done this way - save parameters in cookie, which next time are used to get script again.
And finally back to the first two magic lines :) After Google loads its script (after executing d.write), there are some functions which uses utmx and utmx_section, as well as definition of these functions, or better to say overriding. I think they are empty at first just because another function can execute it before its real definition, and having empty functions nothing will happen (and no JS error), otherwise script would not work. E.g. after first iteration there is some data, which is used to make real definition of these functions and everything starts to work :)
The first 2 functions are in fact empty, and are probably overridden later on.
The third function is an anonymous self-executing function. The brackets are a convention to make you aware of the fact that it is self executing.
the "f" function looks up the value given to it in the document's cookies and returns it. Then a new script tag is written to document (and requested from server) with these values as part of its URL.
I need to let a piece of code always run independently of other code. Is there a way of creating a thread in javascript to run this function?
--why setTimeout doesn't worked for me
I tried it, but it runs just a single time. And if I call the function recursively it throws the error "too much recursion" after some time. I need it running every 100 milis (it's a communication with a embedded system).
--as you ask, here goes some code
function update(v2) {
// I removed the use of v2 here for simplicity
dump("update\n"); // this will just print the string
setTimeout(new function() { update(v2); }, 100); // this try doesn't work
}
update(this.v);
It throws "too much recursion".
I am assuming you are asking about executing a function on a different thread. However, Javascript does not support multithreading.
See: Why doesn't JavaScript support multithreading?
The Javascript engine in all current browsers execute on a single thread. As stated in the post above, running functions on a different thread would lead to concurrency issues. For example, two functions modifying a single HTML element simultaneously.
As pointed out by others here, perhaps multi-threading is not what you actually need for your situation. setInterval might be adequate.
However, if you truly need multi-threading, JavaScript does support it through the web workers functionality. Basically, the main JavaScript thread can interact with the other threads (workers) only through events and message passing (strings, essentially). Workers do not have access to the DOM. This avoids any of the concurrency issues.
Here is the web workers spec: http://www.whatwg.org/specs/web-workers/current-work/
A more tutorial treatment: http://ejohn.org/blog/web-workers/
Get rid of the new keyword for the function you're passing to setTimeout(), and it should work.
function update(v2) {
try {
dump("update\n");
} catch(err) {
dump("Fail to update " + err + "\n");
}
setTimeout(function() { update(v2); }, 100);
}
update(this.v);
Or just use setInterval().
function update(v2) {
try {
dump("update\n");
} catch(err) {
dump("Fail to update " + err + "\n");
}
}
var this_v = this.v;
setInterval(function() {update(this_v);}, 100);
EDIT: Referenced this.v in a variable since I don't know what the value of this is in your application.
window.setTimeout() is what you need.
maybe you should to view about the javascirpt Workers (dedicated Web Workers provide a simple means for web content to run scripts in background threads), here a nice article, which explain how this works and how can we to use it.
HTML5 web mobile tutororial
U can try a loop instead of recursivity