slow down code until ajax function is over? - javascript

I want to call fillContent then later called beginEditingQuestion
fillContent(cid, "questions");
beginEditingQuestion(qid);
The problem is that I can't rung beginEfitingQuestion until all the ajax in fillContent is done. Is there an elegant way to delay the code? The only idea I can think of is to make a totally new function fillContentAndBeginEditingQuestion where I copy and paste fillContent into the new function and in the final ajax call add in beginEditingQuestion. This doesn't seem very elegant to me, I want to reuse fillContent in other contexts. What should I do?

You can make fillContent take a callback parameter, and have it call the callback when it's done. Basically, you'd just add callback (); into the body of fillContent at the very end. In this way, you'd write something like this, and have the passed function executed at the end:
fillContent (cid, "questions", function () { beginEditingQuestion (qid); });

I don't think you want to "slow", rather you want to wait for something to complete before the next piece of work is begun.
A pattern for this, used in many languages, is to use Events.
Conceptually:
You register an interest in a "DoneFillingContent" event, saying please call beginEditingQueue() when the event arrives.
fillContent has the repsonsibility of emiting an event to all interested parties. He doesn't realise what beginEditingQueue() does, it just a piece of work to be done on completion.
In the simplest version of the pattern, you just allow one callback function.

It sounds like you need to change "fillContent" so that one of its parameters is a callback function that is invoked when the AJAX returns.

Related

Javascript wait for function to finish

I know this question has been asked tens if not hundreds of times, but I turned google purple and still can't find an answer that suits my case.
I have a set of three functions that I need to call one from within the other, and need each function to finish before the one that calls it continues. Currently what happens is that a function would call another one, and then continue before the function it called finished.
Most of what I have seen says to use callback functions, my problem is that my inner most function is taken from a library, thus I can not adapt it to accept a callback function as a parameter. I also saw things on timeouts, but I do not want to force my code to wait any longer than it has to, I just want it to continue once the function it calls finished.
I just want everything to work synchronously, like I am used to from any other language.
To illustrate my current code, I am using three.js and this is (basically) what I have:
firstfunction(){
secondFunction();
}
secondFunction(){
var loader = new THREE.JSONLoader(); //loader is an object from three.js library
//loader.load is a three.js function that calls thirdFunction that I made. I can not make loader.load send a callback function to thirdFunction, as thirdFunction takes its arguments from three.js library
loader.load(url, thirdFunction);
}
thirdFunction(){ //this is a function that gets called from loader.load
//do stuff
}
I feel like I am missing something very trivial, but as I said I can't find anything online that fits my needs.
Any help would be greatly appreciated
Even if some libraries and apis allow you to do things synchronously, this is not how javascript should work. Even if you're used to this in other languages, javascript is different.
The answer to your question probably is 'this is not possible'.
Try to lean javascript the correct way, instead of making it behave like other languages.
However, there's some hope. Once you understand fully how callback works, and structure your code around that, you might realize that Promises is a better pattern that callbacks. Promises still need a sort of call-back and are still asynchronous, but it's easier to make your code easier to read.
Then once you fully understand promises, you might be able to use async and await. New browsers support this. These 2 keywords make a lot of your code 'look' synchronous like you're used to, but it's still asynchronous. It's pretty great.
Edit
I wanna address the follow sentence more directly:
//loader.load is a three.js function that calls thirdFunction that I made. I can not make loader.load send a callback function to thirdFunction, as thirdFunction takes its arguments from three.js library
Do you really need to send that third function another callback? What kind of callback is this? Is it just another function it should always call?
You can just call another function normally from your ThirdFunction. If you need it to be variable, you can probably just assign that function to a variable. Functions can access variables from their parent scope. For example:
var callback = '..'; // assuming this a callback.
thirdFunction(){
callback();
}
If only your second function knows what the callback should be, you might need to structure it like this:
secondFunction(){
var loader = new THREE.JSONLoader(); //loader is an object from three.js library
var callback = '...';
loader.load(url, function() {
thirdFunction(callback);
});
}

javascript - Order of executing functions

I have some javascript functions being called on Document Ready:
fogFields();
getLoS();
getShips();
startGame();
getNextMove();
However, it is as though getNextMove() is being called first, most likely as all it does is an ajax call and alerts the result. All the other functions have more work, so, the first thing that happens on load is the getNextMove() alert, and in the background you can see that none of the other functions did their work. Until I click OK on the alert window, no results are shown. Can I make it so that until a function finishes, the next wont even start. Some functions call their own extra functions before they finish, and that works in order, but I cant do that with the whole code...
Given the code in your question, there is no way the call to getNextMove can be invoked before startGame has been exited, regardless of their contents.
It may be true that a function that has been scheduled asynchronously (via timeout, AJAX callback etc.) within startGame completes at any time before or after the invocation of getNextMove, but this is a separate issue. To resolve that issue we need to know more about the contents of the functions.
If the other functions have an AJAX call in them, then these AJAX calls most certainly take a callback argument, which is a function that gets executes, when the AJAX call has finshed. Now, if you want to execute your functions in a way, the one function starts when the AJAX call of the previous function finished, you can add an additional callback argument to your own functions, which will then be passed to the AJAX calls. This should illustrate what I mean:
function logFields(callback) {
ajaxCall(callback);
}
function getLoS(callback) {
ajaxCall(callback);
}
function getShips(callback) {
ajaxCall(callback);
}
function startGame(callback) {
ajaxCall(callback);
}
function getNextMove() {
}
fogFields(function(){
getLoS(function(){
getShips(function(){
startGame(function(){
getNextMove();
});
});
});
});
If all of your functions use a ajax call then just use promises.
Simply return it, for example:
function fogFields(){
return $.ajax();
};
and then just use .then:
fogFields().then(getLos());
more information about deffered object on jquery doc page if you use it.
Or implementation in pure javascript you can find here and more theory here.
or another option, which I will not recommend you is to set async param in $.ajax call to false. Again it's for case you use jQuery.

Two Javascript Function in an Onclick

Is it possible to have two function calls in a onclick? I tried doing something like:
onclick="function1(); function2();"
Doing that it only executes the first function, but not the second. Anyway to have both in the onclick? It code be on the client side or in the code behind in C#.
Thanks!
I'd say either function1 or function2 is undefined, or function1 is throwing an exception, or (with respect) you're simply wrong that both of them don't get called. In the normal case, both will be called (proof).
That's not to say it's a good idea. You'd be much better off defining a third function that calls the other two, or even better using DOM2 handlers and doing away with onclick entirely.
That should work. You may have an error in function1() which causes everything after it to not be executed.
That should be fine unless you have an error in one of your functions. However, I encourage other developers to have one function that calls both functions, then call it in your onclick event.
function function3()
{
function1();
function2();
}
... onclick="function3();"

Implement a callback with a function that doesn't accept a callback?

This is a newbie question: I have a pre-existing function that I would like to have call another function when it is finished, however, it does not accept a callback nor of course call one. I can modify this code to accept and call a function however this got me thinking about whether JavaScript supports doing this ... I would think it does but I've never had reason to find this out, I'm assuming it's necessary when working with libraries where we cannot change the code to our liking. Thanks.
The only time you need a callback is when you are doing something asynchronous, such as:
making an HTTP request (and waiting for a response)
animating something, one frame every time period until it is done
waiting for the user to click a button
All of these are considered "done" when something happens, but there is no generic way to determine when the something has happened. You need something custom for each one.
If you aren't waiting for something, then you can just call one function after the other (foo();bar();) and not need to fiddle around with callbacks.
So…
It might be possible to do what you want, but we can't tell you a generic way to achieve it.
This is a bit of a hack, and i'm sure there's tidier ways to do this with polymorphism, but you can treat the function as a variable and re-assign it somewhat:
Say you start with this function:
function originalFunctionName()
{
// do something
}
you can assign the existing function to a new name:
var backupOfOriginal = originalFunction;
then you can define a new function over the original name:
var originalFunctionName = function()
{
// do something else
// call backup function
backupOfOriginal();
}
then if you call the original function name:
originalFunctionName();
all the code will execute.
You can always create a new function which calls that function and provides you with opportunities to do something else before and after it is called. Underscore.js provides .wrap() to do exactly that sort of thing and return you a function you can call instead of the first function.
That just gives you a new function to call instead of your original function, if you want every spot that called the original function to get the new behavior instead, you could take advantage of JavaScript's prototypal inheritance to replace the original function with your new version of it.
Create a wrapper function that calls the original function, then one you pass in.
If the original function is an Ajax call and you're trying to replace one of its handlers, that's a different issue, though you might be able to use jQuery's $.when(original).then(function () { ... }) depending on your actual needs.

Javascript: Trigger action on function exit

Is there a way to listen for a javascript function to exit? A trigger that could be setup when a function has completed?
I am attempting to use a user interface obfuscation technique (BlockUI) while an AJAX object is retrieving data from the DB, but the function doesn't necessarily execute last, even if you put it at the end of the function call.
Example:
function doStuff() {
blockUI();
ajaxCall();
unblockUI();
};
Is there a way for doStuff to listen for ajaxCall to complete, before firing the unBlockUI? As it is, it processes the function linearly, calling each object in order, then a separate thread is spawned to complete each one. So, though my AJAX call might take 10-15 seconds to complete, I am only blocking the user for just a split-second, due to the linear execution of the function.
There are less elegant ways around this...putting a loop to end only when a return value set by the AJAX function is set to true, or something of that nature. But that seems unnecessarily complicated and inefficient.
However you're accomplishing your Ajax routines, what you need is a "callback" function that will run once it's complete:
function ajaxCall(callback){
//do ajax stuff...
callback();
}
Then:
function doStuff(){
blockUI();
ajaxCall(unblockUI);
}
Your AJAX call should specify a callback function. You can call the unblockUI from within the callback.
SAJAX is a simple AJAX library that has more help on how to do AJAX calls.
There's also another post that describes what you're looking for.
You can do a synchronous xhr. This would cause the entire UI block for the duration of the call (no matter how long it might take).
You need to redesign your program flow to be compatible with asynchronus flow, like specifying a callback function to be called after the response is processed. Check out how Prototype or JQuery or ... accomplishes this.
The answer is simple, you have to call unblockUI() when your ajax request returns the result, using jQuery you can do it like this:
function doStuff(){
blockUI();
jQuery.ajax({
url: "example.com",
type: "POST", //you can use GET or POST
success: function(){
unblockUI();
}
});
}
It sounds to me that you want the user to wait while info is being fetched from the db. What I do when I make an Ajax call for some info from the database is to display an animated gif that says "getting it..." - it flashes continually until the info is retrieved and displayed in the webpage. When the info is displayed, the animated gif is turned off/hidden and the focus is moved to the new info being displayed. The animated gif lets the user know that something is happening.

Categories

Resources