Running Javascript functions in order (one after the other) - javascript

when I try the following:
if(myFunction() == "3") {
alert('its three!');
}
my function returns undefined, when I know that it is actually returning 3.
Is this because javascript evaluates the if statement before the function can return a value?
if so how can I do something like this:
var result = myFunction();
// Wait until result is there
if(result == "3") {
alert("its three!");
}

To troubleshoot your problem, try calling the "alert" function with the return value of your function as the argument:
var result = myFunction();
// For debugging
alert(result);
if(result == "3") {
alert("its three!");
}
If the contents of the alert box are "undefined", your function is not in fact returning a value, and just assigning that non-existent result to a variable is not going to help. Check to make sure myFunction looks like:
function myFunction() {
// Perform calculations
var n = 10 - 7;
// Return result
return n;
}
The JavaScript interpreter requires neither functions to return values nor return statements to be used. That means you should double-check that there is in fact a return statement. If you are assigning the result to a variable first, that can be one way you could miss that return statement.
If you are dealing with Ajax requests, jQuery "modal dialogs," or similar constructs, it is not even possible for a function to return a value in this way (when the button is clicked or the request completes, that is). To fix the problem, your function needs to accept a callback function as a parameter. Then when done, it must call that function, passing the "returned value" as an argument:
function myFunction(callback) {
// Start an AJAX request
var x = new XMLHttpRequest();
x.open('GET', '/domath.php?expression=10-7', true);
x.onreadystatechange = function() {
if(x.readyState == 4 && x.status == 200) {
// Call callback function, "returning" a value asynchronously
callback(x.responseText);
}
};
x.send();
}
And then your main code would be:
myFunction(function(result) {
// For debugging
alert(result);
if(result == "3") {
alert("its three!");
}
});

What it sounds like is that your javascript code is calling the function before the function or the elements it accesses (ie something in the DOM) have been fully loaded, which is why the function call is returning undefined instead of '3'.
The way to prevent this is to defer calling the function until the DOM has finished loading.
This is typically done by having the function call in your document.onload() method, which only gets run when the page has finished loading, or by using jQuery's $.ready() method, which again waits until the page is ready before being run.
Hope that helps.

I am a little unclear as to what you are doing from the description. Try this to see if its what you wanted:
function MyFunction(){
var result
// Do something here
//dummy:
result = 3;
return result;
}
var Testing = MyFunction();
alert(Testing);
if (Testing == 3) {
alert("Holy Cow! Its 3!");
}

Related

What does Return do in here?

I have problem with 'return' means in this code.
1.
function func4() {
var str = "function works.";
console.log(str);
}
func4();
2.
function func4() {
var str = "function works.";
return str;
}
var value = func4();
console.log(value);
Both of them, their result is 'function works.'.
I know that return used for exit function but I'm still confuse when I have to use return exactly.
Sorry about my super basic question :(
As far as I understand 'return' assigns value to a function and returns it, so you're displaying function's value. In the first case you are just simply invoking a function to display a string.
Let's analize this two scenarios:
You have a function that initialize a variable with a predefinided value, and then, you log the value. Then, outside the function you execute it
You have the same variable but with the difference that instead of loggin the value inside the function, you returned it from it. So you can initialize the funcion and store the value on another variable var value = func4();.
Let me try to explain it with some requirements.
I want a function which returns me some data instead of passing a variable and updating the variable in function.
You call a function and it is always best to test negative scenarios first. So in case of negative scenario you can return it from there it self.
In your second case if you see you are getting a value from that function and then printing it. Same thing you can not do using first function.
Always there are workarounds for everything. In the end it depends on your need and what is best suited for that situation.
Both of those functions don't equal the same thing, but they do log the same string.
func4() in #1 is equal to undefined, because it returns nothing.
func4() in #2 returns (gives back) the value "function works.", a string, which is then given to console.log outside of the function.
function func1() {
var str = "function works.";
// console.log(str);
}
func1();
function func2() {
var str = "function works.";
return str;
}
// console.log(func2());
console.log(func1() === undefined);
console.log(func2() === 'function works.');
If you want to use the func4() value for further calculations without calling it again, then you would return {value}.
For e.g
function func4(userInput) {
return userInput % 2 == 0;
}
var response = func4(userInput);
if(response == true) {
console.log('user entered an even number');
} else {
console.log('user entered a odd number');
}
// from here you can use the value of response n times without calling the function again.
Whereas, if you don't return then you will have to call the function x number of times whenever you want to re-user the response of it.
function func4(){
var str = "function works.";
return str;
}
var value = func4();
console.log(value);
//here return means you are returning the value of variable 'str'.
You can find the details here.
https://learn.microsoft.com/en-us/cpp/c-language/return-statement-c?view=vs-2019#:~:text=A%20return%20statement%20ends%20the,value%20to%20the%20calling%20function

JavaScript Functions , return undefined

Hello Everyone hope you all doing great ,
this is my code , function with name and callback
taking the name to callback function to make return the name and console.log it
if i
function doSomething(name,callback) {
callback(name);
}
function foo(n) {
return n;
}
var val = doSomething("TEST",foo);
console.log(val);
i got undefined .
if i
function doSomething(name,callback) {
callback(name);
}
function foo(n) {
console.log(n);
}
var val = doSomething("TEST",foo);
that works fine and console.log the TEST name .
So why the return not working ?
thanks
Your doSomething() function doesn't return anything, which means an assignment using it will be undefined. But, that's not really the problem here.
The underlying problem is that you seem to be mixing two different data processing patterns here: if you're writing purely synchronous code, then use returning functions (which immediately return some value). If you need asynchronous code, then use a callback (which will "eventually" do something). Mixing those two patterns is a recipe for problems and frustration:
Either:
don't name your function a "callback", and have it return its processed value, or
make the callback responsible for doing whatever it is you were going to do with val.
Case 1:
function doSomething(data, processor) {
return processor(data);
}
function passThrough(v) { return v; }
var val = doSomething("test", passThrough);
// immediately use "val" here in for whatever thing you need to do.
Case 2:
function doSomething(data, callback) {
// _eventually_ a callback happens - for instance, this
// function pulls some data from a database, which is one
// of those inherently asynchronous tasks. Let's fake that
// with a timeout for demonstration purposes:
setTimemout(() => callback(data), 500);
}
function handleData(val) {
// use "val" here in for whatever thing you need to do. Eventually.
}
doSomething("test", handleData);
And if you want to go with case 2, you really want to have a look at "Promises" and async/await in modern Javascript, which are highly improved approaches based on the idea of "calling back once there is something to call back about".
2021 edit: a third option since original writing this answer is to use the async/await pattern, which is syntactic sugar around Promises.
Case 3:
async function doSomething(input) {
// we're still _eventually_ returning something,
// but we're now exploiting `async` to wrap a promise,
// which lets us write normal-looking code, even if what
// we're really doing is returning a Promise object,
// with the "await" keyword auto-unpacking that for us.
return someModernAsyncAPI.getThing(input);
}
function handleData(val) {
// ...
}
async function run() {
const data = await doSomething("test");
handleData(data);
}
run();
function doSomething(name,callback) {
callback(name);
}
function foo(n) {
console.log(n);
return n;
}
var val = doSomething("TEST",foo);
Take a look at above code. When you call doSomething, which internally executes foo it prints on the console because thats what console.log is for. However, after this statement it returns n as well which then is received in doSomething. But its not being returned. To put it simply, what you are mainly doing is
function doSomething(name,callback) {
const returnValue = callback(name);
}
If you call the above method, it will return undefined. To make it return correct value, you have to call "return returnValue". Similary you have to say
return callback(name)
Hope this helps.
Happy Learning
Inorder to assign the returning value/object of a function(in this case doSomething, it should have a return statement. Else the function returns nothing, so when you assign that to val, it is still undefined.
So you modify your code like this:
function doSomething(name,callback) {
return callback(name);
}
function foo(n) {
return n;
}
var val = doSomething("TEST",foo);
console.log(val);
undefined is implicitly returned if you don't have a return in your function.
when you call var val = doSomething("TEST",foo), you are aligning the return value of doSomething to val, which is undefined.
function doSomething(name,callback) {
return callback(name);
}
function foo(n) {
return n;
}
var val = doSomething("TEST",foo);
console.log(val);

protractor custom expected condition fails with error

I'm trying to wait the browser with browser.wait with a custom ExpectedCondition like this
The FunctionReturningANumber returns only a number and the numberToCheck is the number to check the number for.
var conditionFn = function () {
return functionReturningANumber(param) === numberToCheck;
};
var condition = EC.and(conditionFn);
browser.wait(condition, 50000);
But if I execute this, I get the error: fn(...).then is not a function which basically says, that it expects an promise. I have looked up the documentation about ExpectedConditions, and the example for a custom one is like this:
// You can define your own expected condition, which is a function that
// takes no parameter and evaluates to a promise of a boolean.
var urlChanged = function() {
return browser.getCurrentUrl().then(function(url) {
return url === 'http://www.angularjs.org';
});
};
And I do not see how here a promise is created. I only see, that a boolean is returned, and the documentation says evaluates to a promise of a boolean which confuses me even more.
This above is for waiting a response from an API, this is caused, because the test triggers a backend process, which protractor then needs to wait for. If there is any better way of doing this, I would greatly appreciate a better way.
I am using protractor 3.1.1.
Any help really apprectiated.
Edit:
I found a way to solve this, for some reason the logical solution by #alecxe didn't work, even if it makes sense:
var numberFound = 0;
var done = false;
var check = function () {
numberFound = functionReturnungANumber(param);
if (numberFound != numberToCheck) {
setTimeout(check, 4000);
} else {
done = true;
}
};
check();
return done;
If I add this to the function and retrieve the return value in the test, which calls this function, and add a browser.wait(function () {
return done;
}); there it works.
It's not beautiful, but for some reason, its the only thing working.... for me at least.
It's just that you don't need to wrap your Expected Condition function into EC.and:
browser.wait(conditionFn, 5000);
Try this one.
browser.wait(conditionFn () {
return url === 'http://www.angularjs.org';
}, 8000);

Break out of function within enumarable.each iteration

I have a Prototype class - within the class i call a function and within this function i do en enumerable.each iteration. If an element within this iteration fails a check i then call another function which then re-calls this same function later. Can i break within this iteration so not only the iteration is ended but nothing else within the function is called.
Say with this code i wouldnt want the console.log to be called if elm.something == 'whatever'. Obviously i could set a variable and then check for this after the function but is there something else that i should be doing?
myFunction: function(el){
el.each(function(elm){
if(elm.something == 'whatever'){
this.someOtherFunction(elm);
}
},this);
console.log("i dont want this called if elm.something == 'whatever'");
}
Just to be clear, in this case the console.log is just placeholder code for the beginnings of some additional logic that would get executed after this loop
You answered it yourself
"Obviously i could set a variable and then check for this after the function"
In this case, you're basically looking to not call the console.log even if elm.something == 'whatever' for a single 'elm'
myFunction: function(el){
var logIt = true;
el.each(function(elm){
if(elm.something == 'whatever'){
logIt = false;
this.someOtherFunction(elm);
}
},this);
logIt && console.log("i dont want this called if elm.something == 'whatever'");
}
The simplest way would be to avoid using each() and instead rewrite using a for loop:
myFunction: function(el){
for(var i in el) {
var elm = el[i];
if(elm.something == 'whatever'){
return this.someOtherFunction(elm);
}
}
console.log("i dont want this called if elm.something == 'whatever'");
}

"Phased" execution of functions in javascript

This is my first post on stackoverflow, so please don't flame me too hard if I come across like a total nitwit or if I'm unable ot make myself perfectly clear. :-)
Here's my problem: I'm trying to write a javascript function that "ties" two functions to another by checking the first one's completion and then executing the second one.
The easy solution to this obviously would be to write a meta function that calls both functions within it's scope. However, if the first function is asynchronous (specifically an AJAX call) and the second function requires the first one's result data, that simply won't work.
My idea for a solution was to give the first function a "flag", i.e. making it create a public property "this.trigger" (initialized as "0", set to "1" upon completion) once it is called; doing that should make it possible for another function to check the flag for its value ([0,1]). If the condition is met ("trigger == 1") the second function should get called.
The following is an abstract example code that I have used for testing:
<script type="text/javascript" >
/**/function cllFnc(tgt) { //!! first function
this.trigger = 0 ;
var trigger = this.trigger ;
var _tgt = document.getElementById(tgt) ; //!! changes the color of the target div to signalize the function's execution
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
trigger = 1 ;
},5000) ;
}
/**/function rcvFnc(tgt) { //!! second function that should get called upon the first function's completion
var _tgt = document.getElementById(tgt) ; //!! changes color of the target div to signalize the function's execution
_tgt.style.background = '#f63' ;
alert('... Someone picked up!') ;
}
/**/function callCheck(obj) {
//alert(obj.trigger ) ; //!! correctly returns initial "0"
if(obj.trigger == 1) { //!! here's the problem: trigger never receives change from function on success and thus function two never fires
alert('trigger is one') ;
return true ;
} else if(obj.trigger == 0) {
return false ;
}
}
/**/function tieExc(fncA,fncB,prms) {
if(fncA == 'cllFnc') {
var objA = new cllFnc(prms) ;
alert(typeof objA + '\n' + objA.trigger) ; //!! returns expected values "object" and "0"
}
//room for more case definitions
var myItv = window.setInterval(function() {
document.getElementById(prms).innerHTML = new Date() ; //!! displays date in target div to signalize the interval increments
var myCallCheck = new callCheck(objA) ;
if( myCallCheck == true ) {
if(fncB == 'rcvFnc') {
var objB = new rcvFnc(prms) ;
}
//room for more case definitions
window.clearInterval(myItv) ;
} else if( myCallCheck == false ) {
return ;
}
},500) ;
}
</script>
The HTML part for testing:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd >
<html>
<head>
<script type="text/javascript" >
<!-- see above -->
</script>
<title>
Test page
</title>
</head>
<body>
<!-- !! testing area -->
<div id='target' style='float:left ; height:6em ; width:8em ; padding:0.1em 0 0 0; font-size:5em ; text-align:center ; font-weight:bold ; color:#eee ; background:#fff;border:0.1em solid #555 ; -webkit-border-radius:0.5em ;' >
Test Div
</div>
<div style="float:left;" >
<input type="button" value="tie calls" onmousedown="tieExc('cllFnc','rcvFnc','target') ;" />
</div>
<body>
</html>
I'm pretty sure that this is some issue with javascript scope as I have checked whether the trigger gets set to "1" correctly and it does. Very likely the "checkCall()" function does not receive the updated object but instead only checks its old instance which obviously never flags completion by setting "this.trigger" to "1". If so I don't know how to address that issue.
Anyway, hope someone has an idea or experience with this particular kind of problem.
Thanks for reading!
FK
You can take advantage of a feature of JS called closure. Combine that with a very common JS pattern called "continuation passing style" and you have your solution. (Neither of these things are original to JS, but are heavily used in JS).
// a function
function foo(some_input_for_foo, callback)
{
// do some stuff to get results
callback(results); // call our callback when finished
}
// same again
function bar(some_input_for_bar, callback)
{
// do some stuff to get results
callback(results); // call our callback when finished
}
The "continuation passing style" refers to the callback. Instead of returning a value, each function calls a callback (the continuation) and gives it the results.
You can then tie the two together easily:
foo(input1, function(results1) {
bar(results1, function(results2) {
alert(results2);
});
});
The nested anonymous functions can "see" variables from the scope they live in. So there's no need to use special properties to pass information around.
Update
To clarify, in your question's code snippet, it's clear that you are thinking roughly like this:
I have a long-running asynchronous
operation, so I need to know when it
finishes in order to start the next
operation. So I need to make that
state visible as a property. Then
elsewhere I can run in a loop,
repeatedly examining that property to
see when it changes to the "completed"
state, so I know when to continue.
(And then as a complicating factor, the loop has to use setInterval to start running and clearInterval to quit, to allow other JS code to run - but it's basically a "polling loop" nevertheless).
You do not need to do that!
Instead of making your first function set a property on completion, make it call a function.
To make this absolutely clear, let's refactor your original code:
function cllFnc(tgt) { //!! first function
this.trigger = 0 ;
var trigger = this.trigger ;
var _tgt = document.getElementById(tgt) ; //!! changes the color...
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
trigger = 1 ;
},5000) ;
}
[Update 2: By the way, there's a bug there. You copy the current value of the trigger property into a new local variable called trigger. Then at the end you assign 1 to that local variable. No one else is going to be able to see that. Local variables are private to a function. But you don't need to do any of this anyway, so keep reading...]
All we have to do is tell that function what to call when it's done, and get rid of the property-setting:
function cllFnc(tgt, finishedFunction) { //!! first function
var _tgt = document.getElementById(tgt) ; //!! changes the color...
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
finishedFunction(); // <-------- call function instead of set property
},5000) ;
}
There's now no need for your "call-check" or your special tieExc helper. You can easily tie two functions together with very little code.
var mySpan = "#myspan";
cllFnc(mySpan, function() { rcvFnc(mySpan); });
Another advantage of this is that we can pass different parameters to the second function. With your approach, the same parameters are passed to both.
For example, the first function might do a couple of calls to an AJAX service (using jQuery for brevity):
function getCustomerBillAmount(name, callback) {
$.get("/ajax/getCustomerIdByName/" + name, function(id) {
$.get("/ajax/getCustomerBillAmountById/" + id), callback);
});
}
Here, callback accepts the customer bill amount, and the AJAX get call passes the received value to the function we pass it, so the callback is already compatible and so can directly act as the callback for the second AJAX call. So this is itself an example of tying two asynchronous calls together in sequence and wrapping them in what appears (from the outside) to be a single asynchronous function.
Then we can chain this with another operation:
function displayBillAmount(amount) {
$("#billAmount").text(amount);
}
getCustomerBillAmount("Simpson, Homer J.", displayBillAmount);
Or we could (again) have used an anonymous function:
getCustomerBillAmount("Simpson, Homer J.", function(amount) {
$("#billAmount").text(amount);
});
So by chaining function calls like this, each step can pass information forward to the next step as soon as it is available.
By making functions execute a callback when they're done, you are freed from any limitations to how each functions works internally. It can do AJAX calls, timers, whatever. As long as the "continuation" callback is passed forward, there can be any number of layers of asynchronous work.
Basically, in an asynchronous system, if you ever find yourself writing a loop to check a variable and find out if it has changed state, then something has gone wrong somewhere. Instead there should be a way to supply a function that will be called when the state changes.
Update 3
I see elsewhere in comments you mention that the actual problem is caching results, so all my work explaining this was a waste of time. This is the kind of thing you should put in the question.
Update 4
More recently I've written a short blog post on the subject of caching asynchronous call results in JavaScript.
(end of update 4)
Another way to share results is to provide a way for one callback to "broadcast" or "publish" to several subscribers:
function pubsub() {
var subscribers = [];
return {
subscribe: function(s) {
subscribers.push(s);
},
publish: function(arg1, arg2, arg3, arg4) {
for (var n = 0; n < subscribers.length; n++) {
subscribers[n](arg1, arg2, arg3, arg4);
}
}
};
}
So:
finished = pubsub();
// subscribe as many times as you want:
finished.subscribe(function(msg) {
alert(msg);
});
finished.subscribe(function(msg) {
window.title = msg;
});
finished.subscribe(function(msg) {
sendMail("admin#mysite.com", "finished", msg);
});
Then let some slow operation publish its results:
lookupTaxRecords("Homer J. Simpson", finished.publish);
When that one call finishes, it will now call all three subscribers.
The definitive answer to this "call me when you're ready" problem is a callback. A callback is basically a function that you assign to an object property (like "onload"). When object state changes, the function is called. For example, this function makes an ajax request to the given url and screams when it's complete:
function ajax(url) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if(req.readyState == 4)
alert("Ready!")
}
req.send(null);
}
Of course, this is not flexible enough, because we presumably want different actions for different ajax calls. Fortunately, javascript is a functional language, so we can simply pass the required action as a parameter:
function ajax(url, action) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if(req.readyState == 4)
action(req.responseText);
}
req.send(null);
}
This second function can be used like this:
ajax("http://...", function(text) {
do something with ajax response
});
As per comments, here an example how to use ajax within an object
function someObj()
{
this.someVar = 1234;
this.ajaxCall = function(url) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
var me = this; // <-- "close" this
req.onreadystatechange = function () {
if(req.readyState == 4) {
// save data...
me.data = req.responseText;
// ...and/or process it right away
me.process(req.responseText);
}
}
req.send(null);
}
this.process = function(data) {
alert(this.someVar); // we didn't lost the context
alert(data); // and we've got data!
}
}
o = new someObj;
o.ajaxCall("http://....");
The idea is to "close" (aliased) "this" in the event handler, so that it can be passed further.
Welcome to SO! Btw, You come across as a total nitwit and your question is totally unclear :)
This is building upon #Daniel's answer of using continuations. It is a simple function that chains multiple methods together. Much like how the pipe | works in unix. It takes a set of functions as its arguments which are to be executed sequentially. The return value of each function call is passed on to the next function as a parameter.
function Chain() {
var functions = arguments;
return function(seed) {
var result = seed;
for(var i = 0; i < functions.length; i++) {
result = functions[i](result);
}
return result;
}
}
To use it, create an object from Chained passing all functions as parameters. An example you can test on fiddle would be:
​var chained = new Chain(
function(a) { return a + " wo"; },
function(a) { return a + "r"; },
function(a) { return a + "ld!"; }
);
alert(chained('hello')); // hello world!
​To use it with an AJAX request, pass the chained function as the success callback to the XMLHttpRequest.
​var callback = new Chain(
function(response) { /* do something with ajax response */ },
function(data) { /* do something with filtered ajax data */ }
);
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if(req.readyState == 4)
callback(req.responseText);
}
req.send(null);
The important thing is that each function depends on the output of the previous function, so you must return some value at each stage.
This is just a suggestion - giving the responsibility of checking whether data is available locally or an HTTP request must be made is going to increase the complexity of the system. Instead, you could have an opaque request manager, much like the metaFunction you have, and let it decide if the data is to be served locally or remotely.
Here is a sample Request object that handles this situation without any other objects or functions knowing where the data was served from:
var Request = {
cache: {},
get: function(url, callback) {
// serve from cache, if available
if(this.cache[url]) {
console.log('Cache');
callback(this.cache[url]);
return;
}
// make http request
var request = new XMLHttpRequest();
request.open('GET', url, true);
var self = this;
request.onreadystatechange = function(event) {
if(request.readyState == 4) {
self.cache[url] = request.responseText;
console.log('HTTP');
callback(request.responseText);
}
};
request.send(null);
}
};
To use it, you would make a call to Request.get(..), and it returns cached data if available or makes an AJAX call otherwise. A third parameter could be passed to control how long the data should be cached for, if you're looking for granular control over caching.
Request.get('<url>', function(response) { .. }); // HTTP
// assuming the first call has returned by now
Request.get('<url>', function(response) { .. }); // Cache
Request.get('<url>', function(response) { .. }); // Cache
I've worked it out and it seems to work perfectly well now. I will post my code later after I have sorted it out. In the meantime, thanks a lot for you assistance!
Update
Tried the code in Webkit (Safari, Chrome), Mozilla and Opera. Seems to work just fine. Looking forward to any replies.
Update 2
I changed the tieExc() method to integrate Anurag's chained function call syntax. Now you can call as many functions as you want upon completion check by passing them as arguments.
If you are not inclined to read the code, try it: http://jsfiddle.net/UMuj3/ (btw, JSFiddle is a really neat site!).
JS-Code:
/**/function meta() {
var myMeta = this ;
/** **/this.cllFnc = function(tgt,lgt) { //!! first function
this.trigger = 0 ; //!! status flag, initially zero
var that = this ; //!! required to access parent scope from inside nested function
var _tgt = document.getElementById(tgt) ; //!! changes the color of the target div to signalize the function's execution
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! simulates longer AJAX call, duration 5000ms
that.trigger = 1 ; //!! status flag, one upon completion
},5000) ;
} ;
/** **/this.rcvFnc = function(tgt) { //!! second function that should get called upon the first function's completion
var _tgt = document.getElementById(tgt) ; //!! changes color of the target div to signalize the function's execution
_tgt.style.background = '#f63' ;
alert('... Someone picked up!') ;
} ;
/** **/this.callCheck = function(obj) {
return (obj.trigger == 1) ? true
: false
;
} ;
/** **/this.tieExc = function() {
var functions = arguments ;
var myItv = window.setInterval(function() {
document.getElementById('target').innerHTML = new Date() ; //!! displays date in target div to signalize the interval increments
var myCallCheck = myMeta.callCheck(functions[0]) ; //!! checks property "trigger"
if(myCallCheck == true) {
clearInterval(myItv) ;
for(var n=1; n < functions.length; n++) {
functions[n].call() ;
}
} else if(myCallCheck == false) {
return ;
}
},100) ;
} ;
}​
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd >
<html>
<head>
<script type='text/javascript' >
<!-- see above -->
</script>
<title>
Javascript Phased Execution Test Page
</title>
</head>
<body>
<div id='target' style='float:left ; height:7.5em ; width:10em ; padding:0.5em 0 0 0; font-size:4em ; text-align:center ; font-weight:bold ; color:#eee ; background:#fff;border:0.1em solid #555 ; -webkit-border-radius:0.5em ;' >
Test Div
</div>
<div style="float:left;" >
<input type="button" value="tieCalls()" onmousedown="var myMeta = new meta() ; var myCll = new myMeta.cllFnc('target') ; new myMeta.tieExc(myCll, function() { myMeta.rcvFnc('target') ; }, function() { alert('this is fun stuff!') ; } ) ;" /><br />
</div>
<body>
</html>
A very simple solution would be to make your first ajax call synchronous. It's one of the optional parameters.

Categories