I have two javascript functions
searchButtonClicked()
hidemap()
The searchButtonClicked() will be called in body onload.
The searchButtonClicked() sometimes not respond. So I want to let it try to execute for 5 seconds and if it dosent execute I want to call hidemap().
Please help. Thanks in advance.
Udy
here is the function
function searchButtonClicked() {
if (inlocatorHubMode) {
locatorHubSearch();
}
else {
search();
}
}
I'm assuming searchButtonClicked is an AJAX request.
If this is the case, you can achieve what you're after using a combination of setTimeout and a callback.
var searchTimeout = null;
function searchButtonClicked(){
searchTimeout = setTimeout(requestFailed, 5000);
//If you're using jQuery, something like this
$.ajax({
url: "service.php",
success: requestSuccess
});
//If you're not, something like this
xmlhttp.onreadystatechange=(function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
requestSuccess();
}
});
}
function requestSuccess(){
clearTimeout(searchTimeout);
//Yay! It succeeded!
}
function requestFailed(){
hideMap();
//It didn't unfortunately =[
}
Edit: An edit was made to say that it's not in fact an AJAX request. Leaving this here in case it's useful to somebody.
There is a function in javascript
window.setTimeout("javascript function",milliseconds);
This functions waits the specified number of milliseconds, and then executes the specified function.
In your case you can set timeout at the beginning of your function.
So that after the specified milliseconds, your second function will execute
Related
I have to call two functions on form submit but i want to make sure that that second function is executed only after the first function is executed.
I do not have control over the first function, so i cannot edit it at all.
function a(et){
//function a script
}
function b(evt){
//function b script
}
from function b is there a way that i can check if function a was completed or executed fully.
if you have no access to a at all then you can't do what you want to do here. No way: JS creates a call object when a function is called, and auto-GC's it when the call is complete. Sadly, the actual mem-management is off limits, so you can't check that. other trickery involves your meddling with the code of function a, which you say you cant get at... so no, you can't do this.
Sorry for that, but it's as the FAQ says: you might not always get the answer you're hoping for, but that doesn't mean the answer you don't like isn't true... :-P
There is, however, a little bit of hope for you: if both function a and b are callbacks or handlers of a submit event, you could look into ways of queueing those calls. Given the jQuery tag .queue() suggests itself
According to Eli Grey you can tested like this:
function foo() {
foo.complete = false;
// your code here
foo.complete = true;
}
foo.complete = false;
if (foo.complete) { // foo execution complete
// your code here
}
Yes, you can, there is a lot of ways to do that, but here is a simple way to make it.
You can use persistent object localStorage.
You can use session object sessionStorage.
function a(evt){
// Asynchronous function
// ... your code here
// before finish function create the persistent object
localStorage.setItem('myObject', 'done');
return;
}
function b(evt){
// Checks if a() function was completed
var _done = localStorage.getItem('myObject');
if(_done && _done == 'done') {
// your code here: the a() function was completed
localStorage.removeItem('myObject');
}
}
I have one function using to get data from text file and alert it in another function.
var library_name; // Global Variable
function getLibraryName(){
jQuery.get('stream.txt', function(data) {
library_name = data.toString().substring(17,data.length);
});
}
function saveFeedback() {
alert(library_name);
}
When saveFeedback is called, it will alert library_name
I have been tried to put it in the same function like this
function saveFeedback() {
jQuery.get('stream.txt', function(data) {
library_name = data.toString().substring(17,data.length);
});
alert(library_name);
}
but it is still keep saying undefined in console
How to solve this out? Without using parameter because saveFeedback function has to be called from somewhere else.
The second parameter to .get is called when the get finishes. You're saying, "fetch stream.txt and when it finishes, execute this function". The following calls saveFeedback when the get is finished:
function getLibraryName(){
jQuery.get('stream.txt', function(data) {
library_name = data.toString().substring(17,data.length);
saveFeedback();
});
}
Because get is asynchronous, your interpreter will instantiate the saveFeedback function before the success function is called (although some sanity checkers like JSLint probably want you to define saveFeedback before getLibraryName.
You shoud use saveFeedback() function in $.get(data) callback, because it it async request and you do not know, when it will be completed.
You can make a hidden input field and attach data to it using $.data();
For example:
function getLibraryName(){
jQuery.get('stream.txt', function(data) {
var library_name = data.toString().substring(17,data.length);
$('#myHiddenField').data('library_name', library_name);
});
}
function saveFeedback() {
alert($('#myHiddenField').data('library_name'));
}
jQuery get initiates an asynchronous call. Asynchronous means that the result from it will return later... maybe a short time later, maybe many seconds later. After kicking off this call, the code then proceeds immediately to the next line which is your alert. This alert occurs before the return from the asynchronous call, so of course the variable is still undefined--it hasn't been set yet.
One way to solve the problem might be to tell jQuery to make the call synchronous. But this is the wrong answer because it will stop the browser from responding to user interaction while the call is occurring. Instead, you need to adjust how you think about asynchronous calls. The basic concept is that instead of having a big function that does things step by step like a normal, procedural recipe (do step 1, then step 2, then step 3), instead you have to set up two different recipes or pieces of code: one to initiate the ajax call and then exit, and one to respond to the result of the ajax call.
Now, you already have two functions. You can't combine them for the reasons I already explained. But, you can chain them, or encapsulate one inside the other:
var library_name;
function saveFeedback() {
alert(library_name);
}
function getLibraryName(){
jQuery.get('stream.txt', function(data) {
library_name = data.toString().substring(17 ,data.length);
saveFeedback(); // this chains the two functions together
});
}
or maybe even better:
var library_name;
function saveFeedback() {
alert(library_name);
}
function receiveLibraryName(data) {
library_name = data.toString().substring(17, data.length);
saveFeedback();
// additional statements here after saving
}
function getLibraryName(){
jQuery.get('stream.txt', receiveLibraryName);
}
The point is that you cannot continue in the next statement as usual within the getLibraryName function. The steps you wish to take after the ajax call must be inside of another function: either in the callback function itself, or in another function called from the callback function.
Try following code:
var library_name;
function getLibraryName(){
jQuery.get('stream.txt', function(data) {
let lbName= data.toString().substring(17,data.length);
saveFeedback(lbName);
});
}
function saveFeedback(lbName) {
library_name = lbName; //If you are using library_name in other code
alert(library_name);
}
You have to define library_name before jquery.get once. Because if the jquery.get doesnt work library_name will not be created by the time u call alert.
please add
var library_name;
as the first line of saveFeedback().
I have an asynchronous Ajax function which runs a command string at the server side and returns the result to the client. It calls a callback to process the result.
function ajaxCall(commandStr,callback){
var url=......//make a url with the command string
jquery.get(url,function(result){
//process the result using callback
callback(result);
});
}
The asynchronous call (ajaxCall) may take a while to be finished but I want it to do the same command after an interval (1000ms).
I want to write a function that is like this:
function ajaxCallRepeated(interval,commandStr,callback)
I tried closures like this:
function ajaxCallRepeated(interval,commandStr,callback){
//This feature uses closures in Javascript. Please read this to know why and how: http://jibbering.com/faq/notes/closures/#clSto
function callLater(param1,param2,param3){
return (function(){
ajaxCall(param2,function(out,err){
if(param3)param3(out,err);
var functRef = callLater(param1,param2,param3);
setTimeout(functRef, interval);
});
});
}
//the first call
var functRef = callLater(interval,commandStr,callback);
setTimeout(functRef, interval);
}
Then I call it like this:
ajaxCallRepeated(2000,"ls",function(result){
alert(result);
});
But it only runs the command 2 times.
How can I write a function that will reschedule itself after it is called as a callback of an asynchronous function?
PS. I want to fire another Ajax call after the previous one is finished. Also, it worth to mention that axashCallRepeated() will be called with various parameters, so several Ajax calls are running in parallel, but for each commandStr, there is only one Ajax call going on, and after the Ajax call returns, another one will be fired after X seconds.
I would not use setTimeout to trigger the second Ajax call ! Because you never know how long it will take and if it's finished !
As far as you tagged your question right and you ARE using jquery you should consider something like this:
$.ajax({
type: 'POST',
url: url,
data: data,
success: function(){
// The AJAX is successfully done, now you trigger your custom event:
$(document).trigger('myAjaxHasCompleted');
},
dataType: dataType
});
$(function(){
//somehwere in your document ready block
$(document).on("myAjaxHasCompleted",function(){
$.ajax({
//execute the second one
});
});
});
So this would ensure that the ajax post is DONE and was successful and now you could execute the second one. I know its not the exact answer to your question but you should consider on using something like this ! Would make it safer I guess :-)
The key to solve this problem is to save a reference to the closure itself and use it when scheduling the next call:
function ajaxCallRepeated(interval,commandStr,callback){
//This feature uses closures in Javascript. Please read this to know why and how: http://jibbering.com/faq/notes/closures/#clSto
function callLater(_interval,_commandString,_callback){
var closure=(function(){
ajaxCall(_commandString,function(out,err){
if(_callback)_callback(out,err);
setTimeout(closure,_interval);
});
});
return closure;
}
//now make a closure for every call to this function
var functRef = callLater(interval,commandString,callback);
//the first call
functRef();
}
It becomes easier to reason about if you separate things up a bit.
For example, the repetition logic doesn't have to know about AJAX or callbacks at all:
function mkRepeater(interval, fn, fnScope, fnArgs) {
var running;
function repeat() {
if (!running) return;
fn.apply(fnScope, fnArgs);
setTimeout(repeat, interval);
}
return {
start: function() { running = true; repeat(); },
stop: function() { running = false; }
};
}
You can use it like this:
var r = mkRepeater(2000, ajaxFunction, this, ["getStuff", callbackFn]);
r.start();
...
r.stop();
I have two javascript functions
function one () {
do something long... like writing jpgfile on disk
}
function two () {
do something fast... like show the file
}
I call it (in jQuery) like this
one ();
two ();
Because function two needs the link file from function one, i need to be sure the execution is completed... so getting the function two in the callback of function one should be the trick.. but how to do that ?
note : I did put an alert ('aaa') between those two functions to let function one complete, and it worked fine... when the alert is commented (removed) nothing works anymore !
You only need to use a callback if you are doing something asynchronous, otherwise it doesn't matter how long something takes, the next function won't run until the first has finished.
A callback is just passing a function as an argument, and then calling it when done.
function one (callback) {
do something long... like writing jpgfile on disk
callback();
}
function two () {
do something fast... like show the file
}
one(two);
Obviously, if you are doing something asynchronous, then you need something that will tell you when it is finished (such as an event firing).
Simple:
function one (callback) {
do something long... like writing jpgfile on disk
if(callback) callback();
}
function two () {
do something fast... like show the file
}
one(two);
Try this,
$.when($.ajax(fuction1())).then(function () {
fuction2;
});
Here fuction1 is your first function to call, and fuction2 is your second function.
I think it's easy if the browser wait for the process inside "one()" to be done before execute the next line of command. The iceberg hit titanic cause it doesn't wait. Then executing this:
one(two) // while two is the callBack parameter
is nothing different from:
one()
two()
I suggest using a setInterval.
function one(){
//--- Write the file to disk
//.....................
}
function runTwo(){
if (check_the_written_file_existence){
clearInterval(t)
two();
}
}
var t = setInterval("runTwo()",500)
The most important point is that if there's an event fires when the "long process" in function "one()" has done, you just need to bind function two to that event. Unless, you must check the result by someway every span of time until it's really done.
If I have an ajax call off fetching (with a callback) and then some other code running in the meantime. How can I have a third function that will be called when both of the first 2 are done. I'm sure it is easy with polling (setTimeout and then check some variables) but I'd rather a callback.
Is it possible?
You could just give the same callback to both your AJAX call and your other code running in the meantime, use a variable to track their combined progress, then link them to a callback like below:
// Each time you start a call, increment this by one
var counter = 0;
var callback = function() {
counter--;
if (counter == 0) {
// Execute code you wanted to do once both threads are finished.
}
}
Daniel's solution is the proper one. I took it and added some extra code so you don't have to think too much ;)
function createNotifier() {
var counter = 2;
return function() {
if (--counter == 0) {
// do stuff
}
};
}
var notify = createNotifier();
var later = function() {
var done = false;
// do stuff and set done to true if you're done
if (done) {
notify();
}
};
function doAjaxCall(notify) {
var ajaxCallback = function() {
// Respond to the AJAX callback here
// Notify that the Ajax callback is done
notify();
};
// Here you perform the AJAX call action
}
setInterval(later, 200);
doAjaxCall(notify);
The best approach to this is to take advantage of the fact that functions are first-order objects in JavaScript. Therefore you can assign them to variables and invoke them through the variable, changing the function that the variable refers to as needed.
For example:
function firstCallback() {
// the first thing has happened
// so when the next thing happens, we want to do stuff
callback = secondCallback;
}
function secondCallback() {
// do stuff now both things have happened
}
var callback = firstCallback;
If both your pieces of code now use the variable to call the function:
callback();
then whichever one executes first will call the firstCallback, which changes the variable to point to the secondCallback, and so that will be called by whichever executes second.
However your phrasing of the question implies that this may all be unnecessary, as it sounds like you are making an Ajax request and then continuing processing. As JavaScript interpreters are single-threaded, the Ajax callback will never be executed until the main body of code that made the request has finished executing anyway, even if that is long after the response has been received.
In case that isn't your situation, I've created a working example on my site; view the source to see the code (just before the </body> tag). It makes a request which is delayed by the server for a couple of seconds, then a request which receives an immediate response. The second request's response is handled by one function, and the first request's response is later handled by a different function, as the request that received a response first has changed the callback variable to refer to the second function.
You are talking about a thing called deferred in javascript as #Chris Conway mentioned above. Similarly jQuery also has Deferred since v1.5.
Check these Deferred.when() or deferred.done()
Don't forget to check jQuery doc.
But to give you some idea here is what I am copying from that site.
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
/* a1 and a2 are arguments resolved for the
page1 and page2 ajax requests, respectively */
var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
if ( /Whip It/.test(jqXHR.responseText) ) {
alert("First page has 'Whip It' somewhere.");
}
});
//Using deferred.then()
$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
.then(myFunc, myFailure);
Something like this (schematic):
registerThread() {
counter++;
}
unregisterThread() {
if (--counter == 0) fireEvent('some_user_event');
}
eventHandler_for_some_user_event() {
do_stuff();
}
You can do this easily with Google's Closure library, specifically goog.async.Deferred:
// Deferred is a container for an incomplete computation.
var ajaxFinished = goog.async.Deferred();
// ajaxCall is the asynchronous function we're calling.
ajaxCall( //args...,
function() { // callback
// Process the results...
ajaxFinished.callback(); // Signal completion
}
);
// Do other stuff...
// Wait for the callback completion before proceeding
goog.async.when(ajaxFinished, function() {
// Do the rest of the stuff...
});
You can join multiple asynchronous computations using awaitDeferred, chainDeferred, or goog.async.DeferredList.