I'm making in code a few requests with JQuery and get. It looks like:
$.get('address1', function() { ... });
$.get('address2', function() { ... });
$.get('address3', function() { ... });
// This code should be runned when all 3 requests are finished
alert('Finished');
So, are there any ways to detect whether there is still processing request and run marked code only when all 3 requests are finished.
Thanks.
You can make use of deferred objects [docs] introduced in jQuery 1.5:
$.when(
$.get('address1', function() { ... }),
$.get('address2', function() { ... }),
$.get('address3', function() { ... })
).then(function() {
alert('Finished');
});
Reference: jQuery.when
The jQuery learning center has a nice introduction to deferred objects / promises.
var isFinished = [];
$.get('address1', function() { isFinshed.push["address1"]; allDone(); });
$.get('address2', function() { isFinshed.push["address2"]; allDone(); });
$.get('address3', function() { isFinshed.push["address3"]; allDone();});
var allDone = function(){
if(isFinished.length < 3)return
alert('Finished');
};
var fin1 = false;
var fin2 = false;
var fin3 = false;
$.ajax({
url: "address1",
success: function(){
fin1 = true;
fnUpdate();
}
});
$.ajax({
url: "address2",
success: function(){
fin2 = true;
fnUpdate();
}
});
$.ajax({
url: "address3",
success: function(){
fin3 = true;
fnUpdate();
}
});
function fnUpdate(){
if(fin1 && fin2 && fin3){
alert('fin');
}
}
var count = 0;
$.get('address1', function() { count++; ... });
$.get('address2', function() { count++; ... });
$.get('address3', function() { count++; ... });
var int = setInterval(function() {
if (count === 3) {
clearInterval(int);
alert('done');
}
}, 10);
Related
I would like to compare data to determine if the div needs to be reloaded.
// <![CDATA[
$(function () {
function reload (elem, interval) {
var $elem = $(elem);
var $original = $elem.html();
$.ajax({
cache : false,
url : '/inbox-header.php',
type : 'get',
success : function (data) {
var result = $.trim(data);
var resu = $.trim($original);
console.log(result);
if (result == resu) {
alert('a');
setTimeout(function () {
reload(elem, interval)
}, interval);
return;
}
$elem.html(data);
setTimeout(function () {
reload(elem, interval)
}, interval);
}
});
}
reload('#inboxheader', 500);
});
// ]]>
When I show the output in the console it looks the same, but the alert never shows, so its always false.
UPDATE:
The output of those variables can be found here, unable to post them here..
http://pastebin.com/abfCk7pH
I dont know why but the trim function did not do his job.
this works:
$(function() {
function reload(elem, interval) {
var $elem = $(elem);
var $original = $elem.html();
$.ajax({
cache: false,
url: '/inbox-header.php',
type: 'get',
success: function(data) {
var opgehaaldedata = data.replace(
/(\r\n|\n|\r)/gm, "");
var orgineledata = $original.replace(
/(\r\n|\n|\r)/gm, "");
if (opgehaaldedata == orgineledata) {
//alert('a');
setTimeout(function() {
reload(elem, interval)
}, interval);
return;
} else {
$elem.html(opgehaaldedata);
setTimeout(function() {
reload(elem, interval)
}, interval);
return;
}
}
});
}
reload('#inboxheader', 500);
});
This question already has answers here:
What is cleanest way to turn Array of JQuery Promises into a JQuery Promise of an Array?
(2 answers)
Closed 6 years ago.
I have another callback/promise issues :-)
I'm trying to implement a series of function each of the function are waiting for a return value from the next one.
I have an ajax call that returns a json on success, in the success
block i'm sending this json to an async function validation.
In validation() I'm loading a script and for each object I sending it to
availability function, i want to wait for the availability to complete and to return value, each value that is return is being
pushed to an array that i want to send it in the end.
I'm having trouble with the callback implementations.
var validArr = [];
function checkStory(callback) {
$.ajax({
url: "",
type: "GET",
data: "",
async: true,
headers: {
Accept: "application/json"
},
success: function(data) {
if (data.isDoc == true) {
_checkDoc(callback);
} else {
if (data.responseObj) {
validation(data.responseObj);
} else {
callback(data.count);
}
}
},
error: function(err) {
console.log("No books");
}
});
}
function validation(responseObj) {
getScript('books.js',
function() {
$.each(responseObj, function(_index, _value) {
var res = aviliabilty(_value);
if (res) {
validArr.push(_index, true);
} else {
validArr.push(_index, false);
}
});
//return after all objects completed execution
return validArr;
}
);
}
function aviliabilty(entry) {
DM.ct.get(entry, function(response) {
if (response) {
for (var idx = 0, adLen = response.ds.length; idx < adLen; idx++) {
var bk = response.ds[idx];
for (var creaIdx = 0, crea = bk.creatives.length; creaIdx < crea; creaIdx++) {
var creative = bk.creatives[creaIdx];
if (creative.type == "line") {
for (var mfIdx = 0, mfLen = creative.Files.length; mfIdx < mfLen; mfIdx++) {
var mediaFile = creative.Files[mfIdx];
if (mediaFile.type == "horror") {
return true;
}
}
} else if (creative.type != "horror") {
return false;
}
}
}
}
});
}
// a function to get the script asynchronously
function getScript(url, success) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
Option 1:
use a callback -
validation(data.responseObj, function(){
})
function validation(responseObj, callback) {
//your code....
callback(validArr)
}
Option 2: Use Promises -
validation(data.responseObj).then(function(validArr){
});
function validation(responseObj, callback) {
var defer = Q.defer()
//your code....
defer.resolve(validArr)
return defer.promise
}
I'm trying to stop with return syntax:
<script>
$(document).ready(function() {
setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
f(data.exists == 0){
alert("0");
} else {
alert("1");
return;
}
});
}, 5000);
});
</script>
The function verifies every 5 seconds if there exists data in my table.
I need to stop the function when data.exists == 1 ( the alert("1") ).
<script>
$(document).ready(function() {
var id;
id = setInterval(function() {
var idRefCopy = id; // You need this otherwise you'll get a reference exception
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if(data.exists == 0){
alert("0");
} else {
alert("1");
clearInterval(idRefCopy);
return;
}
});
}, 5000);
});
</script>
You have to define the interval inside a variable, and then clear it. Try this:
<script>
$(document).ready(function() {
var interval = setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if(data.exists == 0){
alert("0");
} else {
clearInterval(interval);
}
});
}, 5000);
});
</script>
You have a typo in the code (i have fixed it here, its a "f" instead of "if" ;) Hope this helps.
You need to clear your interval, this will prevent your function from being fired again. See this for interval reference.
This should be your code:
$(document).ready(function() {
var i = setInterval(function() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
f(data.exists == 0) {
alert("0");
} else {
alert("1");
clearInterval(i);
}
});
}, 5000);
});
How about clearInterval?
var myVar = setInterval(function(){myTimer()},1000);
function myTimer()
{
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML=t;
}
function myStopFunction()
{
clearInterval(myVar);
}
source: W3Schools
I strongly suggest you do not hit your server unless you know your ajax was done
This example will check, but only after the server returned
var counter = 0;
function checkData() {
var url = "../view/anychange.php";
$.getJSON(url, function(data) {
if (data.exists == 0) {
$("#someContainer").html("Not yet on attempt #"+(counter++));
setTimeout(checkData,5000);
} else {
$("#someContainer").html("found on attempt #"+(counter++));
}
});
}
$(function() {
checkData();
});
i have a problem with a InfiniteScrolls calls, this is a part of code in 'Friends' for example:
var InfiniteScrollView = Backbone.View.extend({
el : window,
container : '#profile-friends',
triggerHeight : 10, //px
events : {
'scroll' : 'throttledDetectBottomPage'
},
initialize : function() {
this.throttledDetectBottomPage = _.throttle(this.detectBottomPage, 1000);
},
detectBottomPage : function() {
var self = this;
var offset = $(this.container).height() - this.$el.height() - this.triggerHeight;
if (this.$el.scrollTop() >= offset) {
self.nextPage();
}
},
stop : function() {
this.$el.unbind('scroll');
},
nextPage : function() {
if (this.collection.activeScroll == true) {
this.collection.nextPage();
if (!this.collection.isPaginated) {
if (this.collection.length == 0) {
this.renderNotFoundPage();
this.stop();
return false;
}
} else {
if (this.collection.length == 0) {
this.renderNotFoundMoreResults();
this.stop();
return false;
}
}
}
},
renderNotFoundMoreResults : function() {
$('#profile-friends').append('No more results');
},
renderNotFoundPage : function() {
var container = $(this.container);
container.html('0 results');
}
});
In this.collection.nextPage() is called 'api/friends/pag', pag = page number.
Here the code of the collection:
// profile friends collection
define(
['underscore',
'backbone',
'models/user'],
function(_, Backbone, User){
var PFriendsCollection = Backbone.Collection.extend({
// Reference to this collection's model.
model: User,
initialize: function(){
this.isPaginated = false;
this.active = false;
},
//Call in render
search: function() {
this.page = 1;
this.isPaginated = false;
this.active = true;
this.fetch();
},
//Call in Infinite Scroll view NextPage
nextPage: function() {
if(this.active) {
this.isPaginated = true;
this.page = parseInt(this.page) + 1;
this.fetch({update: true});
}
},
// Url, points to the server API
url: function() {
return 'api/pfriends/' + this.page;
},
// Url, points to the server API
// ATM it is just a json test file
parse: function(response){
// extract items from response.
return response.items;
}
});
return new PFriendsCollection;
});
I created this view in the render() function of FriendsView, and down I surje a problem: i go bottom and trigger launch, but he launch a lot of times if i move the scroll, he call api/pfriends/2, api/pfriends/3, api/friends/4 (For example, is random the number of calls) in the same moment, because he don't wail the first response and launch trigger :(
I do not know where to put a trigger, result or something that blocks the execution of that scroll trigger whenever there pending fetch response.
Thanks =)
fetch returns a jQuery deferred, so you could try this in your collection's nextPage:
return this.fetch({update: true});
Then in your view:
nextPage : function() {
if (this.collection.activeScroll == true && !this.updating) {
var self = this;
this.updating = true;
// function passed to 'always' is called whether the fetch succeeded or failed
this.collection.nextPage().always(function(){
self.updating = false;
if (!self.collection.isPaginated) {
if (self.collection.length == 0) {
self.renderNotFoundPage();
self.stop();
return false;
}
} else {
if (self.collection.length == 0) {
self.renderNotFoundMoreResults();
self.stop();
return false;
}
}
}
}
},
You might want to actually use done and fail instead of always. Check the documentation for more info.
here i am trying to achieve infinite scrolling but what happens when i am scrolling too fast it fire multiple ajax request with same parameter , which cause same data again n again.how overcome from this problem pls help.
(function( $ ){
$.fn.scrollPagination = function(options) {
var opts = $.extend($.fn.scrollPagination.defaults, options);
var target = opts.scrollTarget;
if (target == null){
target = obj;
}
opts.scrollTarget = target;
return this.each(function() {
$.fn.scrollPagination.init($(this), opts);
});
};
$.fn.stopScrollPagination = function(){
return this.each(function() {
$(this).attr('scrollPagination', 'disabled');
});
};
var itr = 2;
$.fn.scrollPagination.loadContent = function(obj, opts){
var target = opts.scrollTarget;
var mayLoadContent = $(target).scrollTop()+opts.heightOffset >= $(document).height() - $(target).height();
if (mayLoadContent){
if (opts.beforeLoad != null){
opts.beforeLoad();
}
$(obj).children().attr('rel', 'loaded');
$.ajax({
type: 'POST',
url: opts.contentPage+"?iteration="+itr,
data: opts.contentData,
success: function(data){
itr++;
$(obj).append(data);
var objectsRendered = $(obj).children('[rel!=loaded]');
if (opts.afterLoad != null){
opts.afterLoad(objectsRendered);
}
}
});
}
};
$.fn.scrollPagination.init = function(obj, opts){
var target = opts.scrollTarget;
$(obj).attr('scrollPagination', 'enabled');
$(target).scroll(function(event){
if ($(obj).attr('scrollPagination') == 'enabled'){
$.fn.scrollPagination.loadContent(obj, opts);
//alert(event.isPropagationStopped());
}
//event.stopPropagation();
//console.log(event.isPropagationStopped());
event.preventDefault();
});
//$.fn.scrollPagination.loadContent(obj, opts);
};
$.fn.scrollPagination.defaults = {
'contentPage' : null,
'contentData' : {},
'beforeLoad': null,
'afterLoad': null ,
'scrollTarget': null,
'heightOffset': 0
};
})( jQuery );
How about firing off the ajax every 10 times the scroll event is triggered?
$.fn.scrollPagination.init = function(obj, opts) {
var target = opts.scrollTarget;
$(obj).attr('scrollPagination', 'enabled');
target.scrollCount = 0;
$(target).scroll(function(event) {
this.scrollCount++;
if (this.scrollCount % 10 == 0) {
if ($(obj).attr('scrollPagination') == 'enabled') {
$.fn.scrollPagination.loadContent(obj, opts);
//alert(event.isPropagationStopped());
}
//event.stopPropagation();
//console.log(event.isPropagationStopped());
event.preventDefault();
}
});
}
I used to call my ajax function when the scroll reaches the bottom of the page.
function nearBottomOfPage() {
return $(window).scrollTop() > $(document).height() - $(window).height() - 200;
}
$(window).scroll(function(){
if (loading) {
return;
}
if(nearBottomOfPage()) {
loading=true;
page++;
$("#place_of_loading_image").show();
$.ajax({
url:'your source',
type: 'get',
dataType: 'script',
success: function() {
$("#place_of_loading_image").remove();
loading=false;
}
});
}
});