jQuery: get() is slower compared to load() - javascript

Obvious question - why?
I need to get from external page table cell, and then inject it to the current page. Complex selectors are used.
This is with .load():
$('#check').load('https://bla-bla-bla .small:contains(Something)+.small:lt(1)');
This is with .get():
function showGetResult()
{
var result = null;
var scriptUrl = "https://bla-bla-bla";
$.get(scriptUrl, function(data) {
result = $(".small:contains(Something)", data).next().html() || "Error";
$('#check').append(result);
});
}
load() get data faster by average 1-2 seconds. But I like get() - since I can have string result, not an object.
Can someone explain why load() works faster?

Because I'd love to find the answer to this myself, I figured it would be nice to provide some resources to help:
AJAX jQuery.load versus jQuery.get:
First of all those two functions are completely different. The 'load' function works with selectors and loads the result of AJAX call inside the selected group and the callback is to handle the "oncomplete" event of the call; while the $.get function is more general and the callback handles the success response of AJAX call where you are free to define any behavior you want. And you can find all this information just by looking at the documentation and specification of the jQuery framework.
Difference between $.ajax() and $.get() and $.load()
$.get() is just a shorthand for $.ajax() but abstracts some of the
configurations away, setting reasonable default values for what it
hides from you. Returns the data to a callback. It only allows
GET-requests so is accompanied by the $.post() function for similar
abstraction, only for POST
.load() is similar to $.get() but adds functionality which allows you
to define where in the document the returned data is to be inserted.
Therefore really only usable when the call only will result in HTML.
It is called slightly differently than the other, global, calls, as it
is a method tied to a particular jQuery-wrapped DOM element.
Therefore, one would do: $('#divWantingContent').load(...)
Seems $.get and $.load both use $.ajax functionality, but in different ways. Perhaps the performance difference lies in the time it takes to parse the returned data?
Maybe the real question is how long do each of these take to send the request to the external URL (a "ping" time), and then how does that compare with processing the returned data?

Related

Reload html page with AJAX

I have a very simple html page with one table that I would like to reload in the background every 5 seconds. In the background means that solution <meta http-equiv="refresh" content="5"> can not be accepted, because the user can observe reloading process then.
I tried the code below, but I observed that RAM usage was quickly raising and after 2-3 minutes firefox browser consumed 70-80% of available memory:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function autoRefresh_div()
{
$("#employee_table").load("index.html");// a function which will load data from other file after x seconds
}
setInterval('autoRefresh_div()', 5000); // refresh div after 5 secs
</script>
Could you please suggest something more efficient?
EDIT:
I forgot to add that in the body of html I have:
<div id="employee_table">
<table>
...
</table>
</div>
And what I wasn't sure is that I use load("index.html") so I'm loading whole page instead of just a div...?
you can also use $.ajax instead of $("").load("url");
as it will only replace the content of the given element in success function means when the AJAX request is successful, so flickering can be prevented.
function autoReload() {
setTimeout(function() {
$.ajax({
url: '/index.html',
success: function(data) {
document.getElementById("employee_table").innerHTML = data;
}
});
autoReload(); // calling again after 5 seconds
}, 5000);
}
autoReload(); // calling the function for the first time
or you can also use $.get
$.get("index.html", function(data, status){
if(status == "success"){
document.getElementById("employee_table").innerHTML = data;
}
});
$.ajax() is the most configurable one, where you get fine grained control over HTTP headers and such. You're also able to get direct access to the XHR-object using this method. Slightly more fine-grained error-handling is also provided. Can therefore be more complicated and often unecessary, but sometimes very useful. You have to deal with the returned data yourself with a callback.
$.get() is just a shorthand for $.ajax() but abstracts some of the configurations away, setting reasonable default values for what it hides from you. Returns the data to a callback. It only allows GET-requests so is accompanied by the $.post() function for similar abstraction, only for POST
.load() is similar to $.get() but adds functionality which allows you to define where in the document the returned data is to be inserted. Therefore really only usable when the call only will result in HTML. It is called slightly differently than the other, global, calls, as it is a method tied to a particular jQuery-wrapped DOM element. Therefore, one would do: $('#divWantingContent').load(...)
It should be noted that all $.get(), $.post(), .load() are all just wrappers for $.ajax() as it's called internally.
More details in the Ajax-documentation of jQuery: http://api.jquery.com/category/ajax/
Hope this will help you.

How should I deal with an ajax get function, that is reused across multiple pages?

I have a web application with booking/reservation-functionality. One of my core functions is to check whether a booking conflicts with other bookings, and this function is used across multiple pages. Its return data is not usually loaded with a page, as it's request parameters are dependent upon user input. In other words:
I have an ajax function, that gets booking data
It is abstracted away into it's own .js file, for reusability
The ajax function is wrapped in a javascript function.
However, an ajax function is not suitable for my intended use. The wrapper function will return nothing, before the ajax call is complete, due to it's asynchronous nature. If i need to execute something with the returned data, it should be inside the success-function of the ajax call, but as I need different things to happen, based on in which page, and which situation the data is needed.
I see three solutions to my problem. I just can't decide which is the best approach, or if there might be a fourth and better option:
1. Skip the abstraction of the ajax function. In other words, just copy/paste it into every function where I need the data, and voilla; I would have the success-condition function available at all times.
2. Pass a succes-function as a parameter. If i need something dynamic to happen, I could make it so, by passing a function to the ajax-wrapper function, and making sure that the passed function accepts the ajax returned data as it's own parameter.
3. Make the ajax call synchronous. Possible, but kind of ruins the concept of ajax (actually I am also using JSON, so that will make ajax into sjoj).
Honestly, I really can't see that either of the solutions stand out as the winner here. I would greatly appreciate any help.
I suggest using an event based approach.
Inside ajax success you can fire (trigger) an event for example booking-check-complete and the specific page handles the event the way it needs.
This way you keep the benefits of the ajax being well - asynchronous and keep the pages decoupled.
For uses like this I use jQuery event mechanism, but there are also other libraries available. Check it out here - trigger
For example in page one you have:
$( document ).on( "booking-check-complete", function( event, param1, param2 ) {
alert( "Hello from page 1" );
});
On the second page you have:
$( document ).on( "booking-check-complete", function( event, param1, param2 ) {
alert( "Hello from page 2" );
});
And in ajax success:
$( document ).trigger( "booking-check-complete", [ "Custom", "Event" ] );
NOTE
You don't need jQuery to use events as described here
This uses plain javascript, but it is not compatible with IE.
var event = new Event('build');
// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);
// Dispatch the event.
elem.dispatchEvent(event);
No. That violates DRY.
Yes. This is idiomatic JavaScript.
No. That locks up the UI (and synchronous XHR is deprecated).
Option 2 is the standout winner.

continue in js program after finishing ajax calls

I have a function with 3 ajax calls
var loadEditModalAddressData(){
loadCountries();
loadStates();
loadDistricts();
};
I want from js to wait, until all ajax calls are finished.
Part of my code
loadEditModalAddressData();
$(document).ajaxStop(function(){
// functionality using requested data
....
}
This worked fine, until I added extra features and figured out that $(document).ajaxStop is called after every complete request(or bunch of requests),not only in certain function scope, which mash up my code functionality.
How do I do that?
The dirty way could be to use a counter in ajaxStop to make sure all three calls have returned. A slightly better way could be to add callbacks to each of your calls and to launch the treatment when the last is received.
However, the best way is probably to use promises.
If you use jQuery to do your calls, you can do stuff like:
$.when(call1, call2, call3).then(function(results){
// your stuffs
});
Where the callX are what returns $.get (or any other jQuery promise).
Have a look here.
Use $.when to wait for multiple defereds/promises. It's synonymous to the native Promise.all().

javascript outside of scope

Based on chrome developer tools a breakpoints I think I'm dealing with a scope issue I can figure out. Is it the way I define the function? The script below is an include js file and the array ' timeStamp I want available for use in other functions without having to call my loadData function everytime.
The timeStamp array goes undefined once it leaves the for loop before it even leaves the function.
var timeStamp = []; // Want this array to be global
function loadData (url){
$.getJSON(url, function(json) {
for (var i=0;i<json.length;i++){
timeStamp.push(json[i].TimeStamp);
}
console.log(inputBITS); //returns the value
});
console.log(inputBITS); //undefined
}
Thank you for anyhelp
It looks like the issue is that getJSON is asynchronous. When it executes and finishes and your code continues on, it indicates only the START of the networking operation to retrieve the data. The actual networking operation does not complete until some time later.
When it does complete, the success handler is called (as specified as the second argument to your getJSON() call) and you populate the timeStamp array. ONLY after that success handler has been called is the timeStamp array valid.
As such, you cannot use the timeStamp array in code that immediately follows the getJSON() call (it hasn't been filled in yet). If other code needs the timeStamp array, you should call that code from the success handler or use some other timing mechanism to make sure that the code that uses the timeStamp array doesn't try to use it until AFTER the success handler has been called and the timeStamp array has been populated.
It is possible to make some Ajax calls be synchronous instead of asynchronous, but that is generally a very bad idea because it locks up the browser during the entire networking operation which is very unfriendly to the viewer. It is much better to fix the coding logic to work with asynchronous networking.
A typical design pattern for an ajax call like this is as follows:
function loadData (url){
$.getJSON(url, function(json) {
// this will execute AFTER the ajax networking finishes
var timeStamp = [];
for (var i=0;i<json.length;i++) {
timeStamp.push(json[i].TimeStamp);
}
console.log(timeStamp);
// now call other functions that need timeStamp data
myOtherFunc(timeStamp);
});
// this will execute when the ajax networking has just been started
//
// timeStamp data is NOT valid here because
// the ajax call has not yet completed
// You can only use the ajax data inside the success handler function
// or in any functions that you call from there
}
And here's another person who doesn't understand basic AJAX...
getJSON is asynchronous. Meaning, code keeps running after the function call and before the successful return of the JSON request.
You can "fix" this by forcing the request to be synchronous with an appropriate flag, but that's a really bad idea for many reasons (the least of which is that you're violating the basic idea of AJAX). The best way is to remember how AJAX works and instead put all your code that should be executed when the AJAX returns, in the right place.

Pattern for wrapping an Asynchronous JavaScript function to make it synchronous

I'm working with a JavaScript API where most of the functions are asynchronous. The API is the WebKit JavaScript Database API which is a binding to a subset of functionality to manipulate SQLite3 databases. I understand the design decision to make things async as to not block and provide a responsive user interface. In my situation I know that my usage of the async API calls will execute fast. Since this is the case I'd like to provide my developers a cleaner and easier to use wrapper API that forces synchronous calls.
Here's the async call
db.executeSql(sqlStatement, function(result) {
// do something with result
});
And here's what I'd like to be able to do
var result = dbWrapper.executeSql(sqlStatement);
// do something with result
Is there a design pattern/way to do this? A written or linked to code example is preferred. The target platform/broswer is Mobile Safari on the iPhone.
Thank you
Sorry, JavaScript does not provide the language primitives (eg. threads or coroutines) to make asynchronous things act synchronously or vice-versa.
You generally* get one thread of execution only, so you can't get a callback from a timer or XMLHttpRequest readystatechange until the stack of calls leading to the creation of the request has completely unravelled.
So in short, you can't really do it; the approach with nested closures on the WebKit page you linked is the only way I know of to make the code readable in this situation.
*: except in some obscure situations which wouldn't help you and are generally considered bugs
StratifiedJS allows you to do exactly that.
There's even an article on how to apply it on browser storage:
http://onilabs.com/blog/stratifying-asynchronous-storage
And this is the Stratified JavaScript library it uses https://gist.github.com/613526
The example goes like:
var db = require("webdatabase").openDatabase("CandyDB", ...);
try {
var kids = db.executeSql("SELECT * FROM kids").rows;
db.executeSql("INSERT INTO kids (name) VALUES (:name);", [kids[0]]);
alert("done");
} catch(e) {
alert("something went wrong");
}
maybe a bit late, but the tech didn't exist back then ;)
You can try something like:
function synch()
{
var done = false;
var returnVal = undefined;
// asynch takes a callback method
// that is called when done
asynch(function(data) {
returnVal = data;
done = true;
});
while (done == false) {};
return returnVal;
}
But that may freeze your browser for the duration of the asynch method...
Or take a look at Narrative JavaScript: Narrative JavaScript is a small extension to the JavaScript language that enables blocking capabilities for asynchronous event callbacks. This makes asynchronous code refreshingly readable and comprehensible.
http://neilmix.com/narrativejs/doc/index.html
Mike
if you are using jQuery Ajax :
$.ajax()
you can set the attribute of asynch to false ,
and then you will have a synch ajax request to the server.
We are using GWT RPC which also has an async API. The solution that we are currently using to make several async calls in serial is call chaining:
callA(function(resultA) {
callB(resultA, function(resultB) {
callC(); //etc.
});
});
This nested approach achieves what you want but it is verbose and hard to read for newcomers. One of the approaches that we have investigated is adding the calls that we need to make to a stack and executing them in order:
callStack = [
callA(),
callB(),
callC()
];
callStack.execute();
Then the callstack would manage:
Invoking the calls in serial (i.e. the wiring in the first example)
Passing the result from one call forward to the next.
However, because Java doesn't have function references, each call on the call stack would require an anonymous class so we stopped short of such a solution. However, you may have more success in javascript.
Good luck!
This doesn't actually implement synchronous operation of the db query, but this was my solution for easy management. Basically use the calling function as the callback function, and test for the results argument. If the function receives results, it parses them, if not, it sends itself as a callback to the query method.
render: function(queryResults){
if (typeof queryResults != 'undefined'){
console.log('Query completed!');
//do what you will with the results (check for query errors here)
} else {
console.log('Beginning query...');
this.db.read(this.render); //db.read is my wrapper method for the sql db, and I'm sending this render method as the callback.
}
}
I am not sure if this is the right place but I cam here searching for answers to making an synchronous calls in Firefox. the solution would be to remove onreadystatechange callback and do a direct call.
This is what I had found and my solution
synchronous call back with rest service

Categories