Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to wait for an event to complete? 1

Status
Not open for further replies.

FancyPrairie

Programmer
Oct 16, 2001
2,917
US
I've created a javascript class (MyClass). In my html page I set var abc = new MyClass();

To simplify, MyClass looks something like this:

function MyClass() {
var c

c.currentDate = null; //line 1
c.IsDropDown = false; //line 2

...

code to dynamically add include files here, but the readyState of the include files must be set to "complete" before executing the next statement. //line 3

return c //line 4
}

How do I execute the code in line 3 and wait for it to finish before executing line 4?

I've tried using setTimeout and setInterval but can't seem to get them to work so that line 4 does not get executed until line 3 finished.
 
The say the devil is in the details, but we have no details at all of how your mystical "line 3" operates. Right now, all we have is "// line 3" which is a comment that would do nothing, so if it does nothing, there can be no bug, surely?

Rant about crystal balls and being psychic aside...

While the usual way of including extra script files is to dynamically create the SCRIPT elements, I'm guessing you're using AJAX to retrieve the file (I assume this because you talk about readyState. I also assume when you say "include files" you're talking about more JS).

If this is the case, you could either switch to using SJAX (i.e. make your asynchronous calls synchronous) - normally done by setting a boolean when opening your AJAX connection, but might be different if you're using a library, or you could switch to creating the SCRIPT elements dynamically.

If this is not the case, then you'll have to lie with the devil and give us those details!

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
I don't want to lie with the devil, but I'll give you the details.
Code:
var s1 = document.createElement("script");
s1.language = "javascript";
s1.src = "function1.js";
document.getElementsByTagName("head")[0].appendChild(s1);

var s2 = document.createElement("script");
s2.language = "javascript";
s2.src = "function2.js";
document.getElementsByTagName("head")[0].appendChild(s2);

var s3 = document.createElement("script");
s3.language = "javascript";
s3.src = "function3.js";
document.getElementsByTagName("head")[0].appendChild(s3);

At this point I need to wait until all 3 of the above are complete. I know the following is not the way to do it, but something like it.
Code:
while ((s1.readyState != 'complete') || (s2.readyState != 'complete') || (s3.readyState != 'complete')) {}

 
I had to do something similar - loading jQuery dynamically into a popup window.

All was well in IE, Fx, Chrome, and Opera... but Safari always took marginally longer, so I ended up doing this:

Code:
var jQueryScript = document.createElement('script');
jQueryScript.type = 'text/javascript';
jQueryScript.src = 'assets/js/jquery-1.3.1.js';
docHead.appendChild(jQueryScript);
attachCode();

function attachCode() {
	if (!jQuery) {
		setTimeout(attachCode, 100);
		return;
	} else {
		// Do stuff here knowing that jQuery has been fully loaded
	}
}

This worked perfectly for me. Putting debug statements in showed that Safari only called the timer usually once or twice, so really it's not a huge lag.

As long as there is something unique in each of the script files you can test for, then you should be good.

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Dan,

I've tried that technique before, but I can't get it to work in my situation. If you notice, MyClass is returning data to abc (i.e. var abc = new MyClass). Note the last statement in MyClass (return c). In your example, it doesn't return c.

For example, one of the include files declares a function that is called from MyClass. Therefore, I have to wait for the readyState to be complete before I call the function. Then I can return c.

Assume that the a function getSomething is located in one of the include files that is begining created dynamically. The Code would have to look something like this:
Code:
var jQueryScript = document.createElement('script');
jQueryScript.type = 'text/javascript';
jQueryScript.src = 'assets/js/jquery-1.3.1.js';
docHead.appendChild(jQueryScript);
attachCode();
c.gotSomething = getSomething
return c

As you can see, the line following attachCode() would be exectuted immediately after attachCode ran once. Of cource attachCode would continue to run until the condition was true, but the line of code "c.getSomething" will have already errored by then.

So my question is, how to I prevent attachCode from returning until the conditions are met?
 
Perhaps the "// Do stuff here knowing that jQuery has been fully loaded" wasn't as obvious as I'd hoped, and perhaps I didn't explain the solution clearly enough.

You move all of the code you want to run AFTER the files have loaded into the function where that comment is.

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Oops missed this bit out:

... and then you can call the functions, and return things from 'attachCode'.

'attachCode' can even be a method of your object - in my original case it was, although I simplified it for the post above, so there's no problem with losing scope as long as you keep the context over the setTimeout (I did this by borrowing Prototype's 'bind' function).

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
OK, so maybe it works... :)

I had tried the setTimeout before but without jQuery. I has missed the fact that you were relying on jQuery to do the work.

Thanks. Your example was a real eye openener.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top