How can I force sync mode on dynatree? - ajax

I'm using Martin Wendt's Dynatree and want to update the tree in Ajax, dynamically and recursively.
For this, I'm using functions like tree.getNodeByKey(nodes[i-1]).appendAjax({});
and tree.activateKey(nodes[i]); in a for loop.
When adding alert("Hello world"); into the loop, my code works correctly 95% or the time. Without it, the code never works.
The problem is obviously coming from the fact that Dynatree is performing its Ajax requests in asynchronous mode, and seem ignoring the async:false, when added to .initAjax and/or .appendAjax:
jQuery('#tree').dynatree("getTree").getNodeByKey(nodes[i-1]).appendAjax({
type: 'POST',
url: "inc/treeNodes.php",
dataType: 'json',
data: {key: nodes[i]},
async:false
});
I tried adding setTimeout (function() {},2000); around the call to .appendAjax, but it prevented this method to work.
Could Dynatree be modified to support asynchronous mode?

Although it does not truly answer the question of running Dynatree in synchronous mode, I found a workaround that almost emulates an Ajax synchronous behavior.
Edit: the following workaround seems working reasonably well on localhost, but not if the site is remote.
Before important calls to Dynatree's method, add a setTimeOut() call at the end of which something will be written to the console.
for (i=1; i < n; i++) {
(...)
setTimeout(function(){console.log('_')}, 3000);
jQuery('#tree').dynatree("getTree").getNodeByKey(nodes[i-1]).appendAjax({...});
(...)
}
The setTimeout does not slower the code as much as the delay would suggest.
For instance, if the loop has three iterations, you don't have to wait 9 seconds (3x 3000) before the work done by all three appendAjax calls complete.
I assume that .appendAjax() calls are performed whilst setTimeout is still running, but the later seem having some magic effect on the document window.
Using setTimeout and trigger console.log() has similar effect as inserting alert(); calls, but is "silent" for the visitor.

Related

Updating website as soon as intermediate plots are ready

Dependent on a selection, made on a website, plots are generated on a server where Flask runs.
The issue that I have is that generating e.g. 10 different plots can take up to 30s. What I like to achieve is to start updating the website as soon as the first plot is ready and then load automatically the others as soon as they are ready.
Currently, the following AJAX function is executed as soon as the user hits the "process" button on the website:
$.ajax({
type: "POST",
url: "/single",
data: { athleteName1: $('#athleteName1').val(), style: $('#style').val()},
success: function (results) {
$('#results').empty().append(results);
$('#results').show();
$('#submitbutton').prop('disabled', false);
},
error: function (error) {
console.log(error);
}
});
On the server site, plots are created and embedded in div-containers. They are subsequently concatenated an returned to the website at once as "diagStr":
#app.route('/single', methods=['POST', 'GET'])
def single():
loop 10 times:
diagStr += generate_plot()
return Markup(diagStr)
Doing it with "Streaming Contents" can only be part of the solution as AJAX waits until the the entire response is received.
Any idea how this is solved with today's technology?
There are multiple way you could achieve this, but some simple examples:
do your looping on the client side, and generate 10 separate Ajax requests, updating the web page when each response is received.
if you don't know in advance on the client side, how many loops you will have, then use a single request and have the server send the response as soon as the first loop is complete, along with a flag indicating whether there are more loops or not - the client can look at this flag and create a new Ajax request if there are more loops.

When to use async false and async true in ajax function in jquery

When to use use async false or async true in an ajax call. In terms of performance does it make any difference ?
example :
$.ajax({
url : endpoint,
type : "post",
async : false,
success : function(data) {
if (i==1){
getMetricData(data)}
else if (i==2)
{
capture = data;
}
}
});
It's not relative to performance...
You set async to false, when you need that ajax request to be completed before the browser passes to other codes:
<script>
// ...
$.ajax(... async: false ...); // Hey browser! first complete this request,
// then go for other codes
$.ajax(...); // Executed after the completion of the previous async:false request.
</script>
When async setting is set to false, a Synchronous call is made instead of an Asynchronous call.
When the async setting of the jQuery AJAX function is set to true then a jQuery Asynchronous call is made. AJAX itself means Asynchronous JavaScript and XML and hence if you make it Synchronous by setting async setting to false, it will no longer be an AJAX call.
for more information please refer this link
It is best practice to go asynchronous if you can do several things in parallel (no inter-dependencies).
If you need it to complete to continue loading the next thing you could use synchronous, but note that this option is deprecated to avoid abuse of sync:
jQuery.ajax() method's async option deprecated, what now?
In basic terms synchronous requests wait for the response to be received from the request before it allows any code processing to continue. At first this may seem like a good thing to do, but it absolutely is not.
As mentioned, while the request is in process the browser will halt execution of all script and also rendering of the UI as the JS engine of the majority of browsers is (effectively) single-threaded. This means that to your users the browser will appear unresponsive and they may even see OS-level warnings that the program is not responding and to ask them if its process should be ended. It's for this reason that synchronous JS has been deprecated and you see warnings about its use in the devtools console.
The alternative of asynchronous requests is by far the better practice and should always be used where possible. This means that you need to know how to use callbacks and/or promises in order to handle the responses to your async requests when they complete, and also how to structure your JS to work with this pattern. There are many resources already available covering this, this, for example, so I won't go into it here.
There are very few occasions where a synchronous request is necessary. In fact the only one I can think of is when making a request within the beforeunload event handler, and even then it's not guaranteed to work.
In summary. you should look to learn and employ the async pattern in all requests. Synchronous requests are now an anti-pattern which cause more issues than they generally solve.

How to wait until the embedded ajax call is completed when injecting my script?

It's Google Chrome extension development. I'm using content script to inject into webpages. However some webpages have their own ajax scripts that change the content dynamically. How do I wait until such scripts are completed, since before their completion my script cannot obtain the correct content?
For example,
1- on Google search result page,
2- I want to append "text" to title of every search result item, which could be easily done by calling,
$('h3').append("text");
3- then listen to the search query change, done by
$('input[name="q"]').change( function(eventObj){
console.log("query changed");
// DOESN'T work
$('h3').append("text");
});
The last line doesn't work probably because at the time it's executed the page is still refreshing and $('h3') is not available. Google uses ajax to refresh the search result when the query is changed on the page.
So the question is how to capture this change and still be able to append "text" every time successfully?
EDIT:
Have tried and didn't work either:
$('h3[class="r"]').delay(1000).append("text");
and using .delay() is not really preferred.
EDIT:
.delay() is simply not designed to solve pause the execution of scripts other than UI effects. An workaround is
$('input[name="q"]').change(function(eventObj) {
setTimeout(function() {
$('h3[class="r"]').append(" text");
}, 1000);
});
But as I argued before, setTimeout() is connection-speed dependent, not preferred because I have to manually balance the time of waiting and the speed of response (of my script).
Although this post is down-voted for god-knows-why I'll still be waiting for an elegant answer.
Maybe with jQuery 1.7+ (or with older version using "live" or "delegate")
$('form').on( "change", 'input[name="q"]', function(eventObj){
console.log("query changed");
$('h3').append("text");
});
If form is another element, change it accordingly.

How are notifications such as "xxxx commented on your post" get pushed to the front end in Facebook? [duplicate]

I have read some posts about this topic and the answers are comet, reverse ajax, http streaming, server push, etc.
How does incoming mail notification on Gmail works?
How is GMail Chat able to make AJAX requests without client interaction?
I would like to know if there are any code references that I can follow to write a very simple example. Many posts or websites just talk about the technology. It is hard to find a complete sample code. Also, it seems many methods can be used to implement the comet, e.g. Hidden IFrame, XMLHttpRequest. In my opinion, using XMLHttpRequest is a better choice. What do you think of the pros and cons of different methods? Which one does Gmail use?
I know it needs to do it both in server side and client side.
Is there any PHP and Javascript sample code?
The way Facebook does this is pretty interesting.
A common method of doing such notifications is to poll a script on the server (using AJAX) on a given interval (perhaps every few seconds), to check if something has happened. However, this can be pretty network intensive, and you often make pointless requests, because nothing has happened.
The way Facebook does it is using the comet approach, rather than polling on an interval, as soon as one poll completes, it issues another one. However, each request to the script on the server has an extremely long timeout, and the server only responds to the request once something has happened. You can see this happening if you bring up Firebug's Console tab while on Facebook, with requests to a script possibly taking minutes. It is quite ingenious really, since this method cuts down immediately on both the number of requests, and how often you have to send them. You effectively now have an event framework that allows the server to 'fire' events.
Behind this, in terms of the actual content returned from those polls, it's a JSON response, with what appears to be a list of events, and info about them. It's minified though, so is a bit hard to read.
In terms of the actual technology, AJAX is the way to go here, because you can control request timeouts, and many other things. I'd recommend (Stack overflow cliche here) using jQuery to do the AJAX, it'll take a lot of the cross-compability problems away. In terms of PHP, you could simply poll an event log database table in your PHP script, and only return to the client when something happens? There are, I expect, many ways of implementing this.
Implementing:
Server Side:
There appear to be a few implementations of comet libraries in PHP, but to be honest, it really is very simple, something perhaps like the following pseudocode:
while(!has_event_happened()) {
sleep(5);
}
echo json_encode(get_events());
The has_event_happened function would just check if anything had happened in an events table or something, and then the get_events function would return a list of the new rows in the table? Depends on the context of the problem really.
Don't forget to change your PHP max execution time, otherwise it will timeout early!
Client Side:
Take a look at the jQuery plugin for doing Comet interaction:
Project homepage: http://plugins.jquery.com/project/Comet
Google Code: https://code.google.com/archive/p/jquerycomet/ - Appears to have some sort of example usage in the subversion repository.
That said, the plugin seems to add a fair bit of complexity, it really is very simple on the client, perhaps (with jQuery) something like:
function doPoll() {
$.get("events.php", {}, function(result) {
$.each(result.events, function(event) { //iterate over the events
//do something with your event
});
doPoll();
//this effectively causes the poll to run again as
//soon as the response comes back
}, 'json');
}
$(document).ready(function() {
$.ajaxSetup({
timeout: 1000*60//set a global AJAX timeout of a minute
});
doPoll(); // do the first poll
});
The whole thing depends a lot on how your existing architecture is put together.
Update
As I continue to recieve upvotes on this, I think it is reasonable to remember that this answer is 4 years old. Web has grown in a really fast pace, so please be mindful about this answer.
I had the same issue recently and researched about the subject.
The solution given is called long polling, and to correctly use it you must be sure that your AJAX request has a "large" timeout and to always make this request after the current ends (timeout, error or success).
Long Polling - Client
Here, to keep code short, I will use jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (eventList) {
// Handle your data here
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data); // handle the `eventName` with `data`
}
}).always(pollTask);
}
It is important to remember that (from jQuery docs):
In jQuery 1.4.x and below, the XMLHttpRequest object will be in an
invalid state if the request times out; accessing any object members
may throw an exception. In Firefox 3.0+ only, script and JSONP
requests cannot be cancelled by a timeout; the script will run even if
it arrives after the timeout period.
Long Polling - Server
It is not in any specific language, but it would be something like this:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Here, hasTimedOut will make sure your code does not wait forever, and anythingHappened, will check if any event happend. The sleep is for releasing your thread to do other stuff while nothing happens. The events will return a dictionary of events (or any other data structure you may prefer) in JSON format (or any other you prefer).
It surely solves the problem, but, if you are concerned about scalability and perfomance as I was when researching, you might consider another solution I found.
Solution
Use sockets!
On client side, to avoid any compatibility issues, use socket.io. It tries to use socket directly, and have fallbacks to other solutions when sockets are not available.
On server side, create a server using NodeJS (example here). The client will subscribe to this channel (observer) created with the server. Whenever a notification has to be sent, it is published in this channel and the subscriptor (client) gets notified.
If you don't like this solution, try APE (Ajax Push Engine).
Hope I helped.
According to a slideshow about Facebook's Messaging system, Facebook uses the comet technology to "push" message to web browsers. Facebook's comet server is built on the open sourced Erlang web server mochiweb.
In the picture below, the phrase "channel clusters" means "comet servers".
Many other big web sites build their own comet server, because there are differences between every company's need. But build your own comet server on a open source comet server is a good approach.
You can try icomet, a C1000K C++ comet server built with libevent. icomet also provides a JavaScript library, it is easy to use as simple as:
var comet = new iComet({
sign_url: 'http://' + app_host + '/sign?obj=' + obj,
sub_url: 'http://' + icomet_host + '/sub',
callback: function(msg){
// on server push
alert(msg.content);
}
});
icomet supports a wide range of Browsers and OSes, including Safari(iOS, Mac), IEs(Windows), Firefox, Chrome, etc.
Facebook uses MQTT instead of HTTP. Push is better than polling.
Through HTTP we need to poll the server continuously but via MQTT server pushes the message to clients.
Comparision between MQTT and HTTP: http://www.youtube.com/watch?v=-KNPXPmx88E
Note: my answers best fits for mobile devices.
One important issue with long polling is error handling.
There are two types of errors:
The request might timeout in which case the client should reestablish the connection immediately. This is a normal event in long polling when no messages have arrived.
A network error or an execution error. This is an actual error which the client should gracefully accept and wait for the server to come back on-line.
The main issue is that if your error handler reestablishes the connection immediately also for a type 2 error, the clients would DOS the server.
Both answers with code sample miss this.
function longPoll() {
var shouldDelay = false;
$.ajax({
url: 'poll.php',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (data, textStatus, jqXHR) {
// do something with data...
}).fail(function (jqXHR, textStatus, errorThrown ) {
shouldDelay = textStatus !== "timeout";
}).always(function() {
// in case of network error. throttle otherwise we DOS ourselves. If it was a timeout, its normal operation. go again.
var delay = shouldDelay ? 10000: 0;
window.setTimeout(longPoll, delay);
});
}
longPoll(); //fire first handler

Does Labjs postpone the execution of the loaded scripts til the DOM is ready?

The question is regarding the http://labjs.com – an awesome library for non-blocking JavaScript loading and dependencies managing.
I've read the docs, but I must be too tired or something – I couldn't find anything regarding DOM ready event. Are the scripts executed after the DOM's ready or not?
Perhaps if I do:
$LAB.script('my-library.js').wait(function(){
// interacting with DOM
});
Will it be safe? Or should I use some kind of $(function() {}) etc.?
Any script loader, by default, acts to unblock script loading from the page's DOM-ready and onload events, at least by intent/definition.
So, the straightforward answer is, NO, LABjs will not block script execution until DOM-ready. Some scripts loaded by LABjs may run before DOM-ready, while others may run after DOM-ready.
If you truly have cases where your code needs to wait for the DOM, you should use a framework like jQuery and use its built-in DOM-ready wrapper $(document).ready(...) to make that logic DOM-ready-safe.
However, there are many cases where people think they need to wait for DOM-ready, when they really don't:
Most people conflate DOM-ready with "all scripts are done loading". If you are simply waiting for DOM-ready because you need to ensure that all your scripts have loaded, this is a mistaken and incorrect assumption to be making. Instead, use the facility of your script loader to determine when all scripts are loaded, and run them at the appropriate time, regardless of the DOM loading. With LABjs, this is as simple as having all your scripts in a single $LAB chain, and having a final .wait() at the end of the chain -- you can be assured that your code in that .wait() callback will not run until all the scripts have loaded and run.
Most people think they need to wait for DOM-ready to do things like attaching event handlers, or firing off Ajax requests. This is also an incorrect assumption. If your code simply queries the DOM for elements to attach event handlers to, or if you are doing nothing with the DOM at all, but are instead making Ajax calls, don't wrap your logic in a DOM-ready wrapper.
On the flip side, many people assume that if your code runs at the end of the body tag, then you don't need to wait for DOM-ready. Wrong. DOM-ready is DOM-ready, regardless where your code is specified.
In general, the only time your code really needs to be wrapped in a DOM-ready wrapper is if it is going to modify the DOM. Otherwise, don't wait for DOM-ready to run your code. Be smart about what is wrapped and what isn't.
How about using jQuery's awesome Deferred object?
This works like a charm:
var waitThenLaunch = function() {
var deferredDocReady = $.Deferred();
$(document).ready(function() {
deferredDocReady.resolve();
});
var deferredScriptsReady = $.Deferred();
// Load your last remaining scripts and launch!!!
$LAB.script('last.js').wait(function(){ deferredScriptsReady.resolve(); });
$.when(deferredDocReady, deferredScriptsReady).done(function() { launchApp(); });
};
$LAB.script('jquery.min.js')
.script('another_script.js')
.script('another_script.js').wait()
.script('another_script.js')
.script('another_script.js').wait(function(){ waitThenLaunch(); });
Find an excellent explanation here: http://www.erichynds.com/jquery/using-deferreds-in-jquery/

Resources