Html web worker not working as expected - javascript

I have below code in main.html
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
w = new Worker("/location_worker.js");
}
w.onmessage = function(event) {
sequence = event.data;
if(Cookies.get("location_tracked") == "done")
{
w.terminate();
w = undefined;
return;
}
if(navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
lon = position.coords.longitude;
$.ajax({
type: "POST",
url: "/api/",
data: {'action':'receive_loc', 'lat': lat,'lon': lon,'enc_data': enc_data,'reached': reached , 'sequence' : sequence },
success: function(jres)
{
res = JSON.parse(jres);
stop = false;
if(res.status == 11)
{
stop = true;
}
if(!stop)
{
//loop continues
}else{
finished = true;
w.terminate();
w = undefined;
return;
}
},
});
},function(code, message) {
$('#error').html("<b>Location Sharing blocked by User..</b>");
});
} else{
alert("Sorry, your browser does not support HTML5 geolocation.");
}
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Workers...";
}
And the location_worker.js contains below
var i = 0;
var ft = 2000;
function timedCount() {
i = i + 1;
self.postMessage(i);
console.log(i);
setTimeout("timedCount()",ft);
}
timedCount();
so for every 2 seconds the ajax will be submitted which is working fine but in below scenarios its not working as expected
for example if sequence 1 and 2 worked fine and tab/browser got inactive and after sometime if i return back to the this page, all the subsequent requests (which are supposed to be sent when tab is inactive) are getting sent at same time (sequence 3,4,5,6,7,8,9 etc).so all these requests are sending same data with same lat lon values which is not supposed to be happened.
someone please let me know what is wrong with this flow.

Your code gets throttled when the tab doesn't have focus. If you want to ensure you don't make two calls within two seconds of one another, use Date.now to track when you did your last call and don't do another call if it's within 2000 of the current Date.now. E.g., just outside your message handler:
var nextAllowed = Date.now();
then just inside it:
if (Date.now() < nextAllowed) {
return;
}
nextAllowed = Date.now() + 2000;
A few things I happened to notice about that code you might want to consider changing:
There's no point to that web worker at all, just put that timer loop in your main page's code.
typeof isn't a function, there's no need to wrap its operand in ().
Don't pass strings into setTimeout, pass in a function reference instead. So: setTimeout(timedCount, ft);
Unless you have var declarations you haven't shown, your code is falling prey to what I call The Horror of Implicit Globals. Declare your variables (like w, sequence, etc.).
If your /api/ endpoint correctly identified the Content-Type of the response, you wouldn't have to use JSON.parse in the ajax callback. In general, try to ensure responses are sent with the correct Content-Type heder.

Related

How do I capture an aborted call or is setting the timeout to 0 correct?

I have a JavaScript client that works in Chrome and Firefox, but fails in IE. Looking at the network trace in the IE debugger it shows that multiple of the AJAX calls have been aborted.
I've been able to get around it by setting the timeout to 0. I'd like to know if this is the correct way to handle my requests being aborted? Basically what could go wrong?
My initial thought was that I should capture and resend on error, and if multiple resubmits do not result in a completed request, finally alert the user. I'd still like to know how to do this even if the setTimeout is the proper way to address my immediate issue.
Also the application will process an excel workbook of addresses, call a web service to add some data to them and then allow the user to download the enhanced file.
This is what I have so far, first in the app.js
var requestWithFeedback = function (args) {
$(".loader").removeClass('hidden');
var oldConfig = args.config || function () { };
args.config = function (xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + localStorage.token);
oldConfig(xhr);
extract: extract;
};
var deferred = m.deferred();
setTimeout(function () { // <== This solved in IE, but is this the way to handle this?
m.request(args).then(deferred.resolve, function(err){
if (err === "Invalid token!"){
m.route('/');
}
})}, 0);
$(".loader").addClass('hidden');
return deferred.promise;
}
From the model.js
app.MarkedAddresses.ProcessAddressBatch = function () {
var requestData = {
Addresses: app.MarkedAddresses.vm.addresses
}
return requestWithFeedback({
method: "POST"
, url: "API/server.ashx"
, data: requestData
, deserialize: function (value) { return value; }
})
.then(function (value) {
var responseJSON = $.parseJSON(value);
$.merge(app.MarkedAddresses.vm.results, responseJSON)
app.MarkedAddresses.vm.currentRecord(app.MarkedAddresses.vm.results.length);
app.MarkedAddresses.vm.progress(Math.max(app.MarkedAddresses.vm.progress(), ~~(app.MarkedAddresses.vm.currentRecord() / app.MarkedAddresses.vm.totalRecords() * 100)));
m.redraw(); //Force redraw for progress bar
return value;
},
function (error) { console.log(error) } // <== I thought error would show up here, but I never hit a breakpoint here.
);
}
Added loops
function process_wb(wb) {
app.MarkedAddresses.vm.results.length = 0;
$('.descending').removeClass("descending");
$('.ascending').removeClass("ascending");
app.MarkedAddresses.vm.progress(.1);
m.redraw();
var header = mapHeader(wb);
var addressJSON = to_json(wb, header);
app.MarkedAddresses.vm.totalRecords(addressJSON.length);
for (var i = 0; (i < addressJSON.length + 1) ; i += 1000) {
app.MarkedAddresses.vm.addresses = addressJSON.slice(i, Math.min(((i) + 1000), addressJSON.length));
app.MarkedAddresses.vm.response(new app.MarkedAddresses.vm.processAddressBatch());
}
}
Why isn't the error triggered in the section of the code?
It seems like I should add a deferred section here, but anything I've tried has been a syntax error.

Javascript : return XMLHttpRequest out of scope

Javascript : return XMLHttpRequest out of scope
I need to return the data from my AJAX call
series: [{
data: ( )
in order to update one of the keys data in dictionary series but my function retrieve does not seem to return the data that I am getting.
var myPopulation = {
series: [{
data: (
function() {
function retrieve() {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var obj = JSON.parse(httpRequest.responseText)
console.log(obj.V1, obj.V2, obj.V3, obj.V4);
var data = [],
time = (new Date()).getTime(),
i;
for (i = -60; i <= 0; i++) {
console.log(obj.V2)
data.push({
x: time + i * 60 * 1000,
y: obj.V2
});
}
myPopulation.series[1].data = data
// ???
console.log(data)
}
}
};
httpRequest.open('GET', "/myCall");
httpRequest.send();
}
retrieve();
}()
)
}],
What should I do to return the value out of the function and update data?
Well, since you are using jQuery tag, I think my answer could be valid and I prefer doing this way for what you need and I understood (it is well explained so please read code comments and check browser console, this can be found at the end of the answer).
Remember that you won't be able to return a XMLHttpRequest because ajax calls are async but you can force an ajax call to be sync in order to get your data on a return statement from any function or do other things as you expected. However, forcing is not a good approach to do because UI will freeze for the user until getting the response back from server and you really don't know how much time that will take (specially if you are expecting a big amount of data to be returned - I know that's not entirely a metric but other factors may apply).
Hope this helps and please take your time and read the following post and user comments: Reasons not to use native XMLHttpRequest - why is $.ajax mandatory?
Live Demo: http://jsfiddle.net/4mbjjfx8/
HTML:
<div id="wrapper">
<div id="loader"></div>
<div id="content"></div>
</div>
jQuery
$(function() {
var series = [], // Your series array
loader = $('#loader'), // UI loader sample
request = {}; // Request params
/**
* Set request method, url and data if needed
* In this case I am sending an object with a text property
* that will be returned from jsfiddle "echo" service
*/
request.method = 'GET';
request.url = '/echo/jsonp/';
request.data = {
text: 'Second message returned from "echo" service'
};
// Send ajax call
retrieveData(request, series, handleData);
// Set loading message to UI
loader.html('Loading...');
// Just do some logging to know how process goes
console.log('Populating series for the first time');
/**
* Populate series for the first time, at this point process
* will go on and after the response from server was finally
* done, process will go to the callback (since ajax calls
* are async).
*/
populate(series);
// Just do some logging to know how process goes
console.log('End populating series for the first time');
});
function populate(series) {
var dummy = {
text: 'First message populated over process'
};
// Set dummy object to series array
series.push(dummy);
};
/**
* Used to make ajax call and return data from server
*/
function retrieveData(cfg, series, callback) {
$.ajax({
type: cfg.method,
url: cfg.url,
data: cfg.data
}).done(function(data, status, xhr) {
// Pass args to callback function if defined
if (callback) callback(series, data);
}).fail(function(xhr, status) {
/**
* Pass args to callback function if defined
* At this point, request wasn't success so
* force data arg at callback to be 'null'
*/
if (callback) callback(series, null);
});
};
/**
* Used to handle data returned from server
* Note: Your series array can be modified here since you
* passed it into the callback
*/
function handleData(series, data) {
var loader = $('#loader');
// Just do some logging to know how process goes
console.log('Populating series from server');
// Check if data is defined and not an empty object
if(data && !($.isEmptyObject(data))) {
// Add it to series array
series.push(data);
}
// Set UI loader empty
loader.html('');
// Retrieve series
showData(series);
};
function showData(series) {
var contentDiv = $('#content');
// Loop process and append to UI
for(var i = 0; i < series.length; ++i) {
contentDiv.append(series[i].text + '<br>');
}
};
You should put retrieve function outside. You can invoke retrieve function. And, It will call ajax. When ajax is success, it will update data of population. Like this.
var myPopulation = {
series: [{
data: undefined
}]
};
function retrieve() {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var obj = JSON.parse(httpRequest.responseText)
console.log(obj.V1, obj.V2, obj.V3, obj.V4);
var data = [],
time = (new Date()).getTime(),
i;
for (i = -60; i <= 0; i++) {
console.log(obj.V2)
data.push({
x: time + i * 60 * 1000,
y: obj.V2
});
}
myPopulation.series[0].data = data
// ???
console.log(data)
}
}
};
httpRequest.open('GET', "/myCall");
httpRequest.send();
}
retrieve();
Assuming you're simply trying to set the value of myPopulation.series[0].data when the array is first defined...
myPopulation.series[1].data = data
...should be...
myPopulation.series[0].data = data;
Also, some parts of you code are missing closing semicolons, closing brackets and/or curly brackets. Please make sure you end all statements with a semicolon and you have an equal number of opening and closing (curly) brackets.
I've tested your code with the above changes. The HTTP request I made returned a simple "Test successful" string, so I've replaced the code which handles the structure of the response text to simply var data = httpRequest.responeText;. This worked fine. Of course, this assumes the code which handles the structure of the returned httpRequest.responeText in your case is correct, as I have no way of knowing what the responseText in your case looks like. If you receive any errors regarding this part of your code, we'll need to see what the responseText looks like before we can help you.
I'm not judging whether you are doing the right thing. Im merely presenting you a working version of your code.
Errors in your code:
You mean to set result of the "function" to data but your function is not returning anything in the first place.
XMLHttpRequest is async so even if you return you will not have the data set, simply because the outer function exited after making the http request setting a callback to trigger when it is completed.
Note: The fix is by making XMLHttpRequest synchronous.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
Here is the corrected version of your code
var myPopulation = {
series: [{
data: (
function() {
function retrieve() {
var httpRequest = new XMLHttpRequest();
var result = []; //[1] just renamed data to result to avoid confusion
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var obj = JSON.parse(httpRequest.responseText)
console.log(obj.V1, obj.V2, obj.V3, obj.V4);
var time = (new Date()).getTime(),
i;
for (i = -60; i <= 0; i++) {
console.log(obj.V2)
result.push({
x: time + i * 60 * 1000,
y: obj.V2
});
}
//myPopulation.series[1].data = data //[2] commented this as it is not necessary
// ???
console.log(result)
}
}
};
httpRequest.open('GET', "/myCall", false); //[3] Added 3rd argument 'false' to make the call synchronous
httpRequest.send();
return result //[4] to convey the result outside
}
return retrieve(); //[5] added return to set it to the data
}()
)
}],
The above code is not tested however. Here is a tested solution http://jsfiddle.net/98f9amo8/1/
The jsfiddle content is different for obvious reasons.
Working with async code means you have to change the way you code because the code is not executed top-down any more.
So, in your case, you would do something like:
var myPopulation = {series: []};
$.get(..., my_function_that_will_format_the_data_after_they_have_been_received);
...
my_function_that_will_format_the_data_after_they_have_been_received() {
// Do stuff here
var formattedData = ...
myPopulation.series.push(formattedData);
// ONLY NOW, myPopulation is ... populated with data.
// So, whatever you use this for, need to be called here
doMagicWith(myPopulation);
}
...
/// Here, myPopulation is empty. doMagicWith(myPopulation) will fail here.
I do not know the context of how you are doing this, seeing no jQuery tells me you wish to avoid it.
So no matter what happens the call is going to take time, and you need to wait for it for whatever you may need to do with it. Loaders can help tell a user that its processing but there are other ways to do that as well. The common factor is no matter what the data is not going to be there when you need it unless you do some sort of callback.
So here is an idea, create your on onload event more or less. There are many things to keep an eye on so jQuery's is probably the most complete, but going to keep it simple here.
window.isLoaded = false;
window.ajaxLoaded = false;
window.onload = function(){
if(window.ajaxLoaded){
onReadyFunction();
}else{
window.isLoaded = true;
}
}
//skipping most of your code, the key part is the retrieve function.
//So its the only part I am going to include in this part.
function retrieve() {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var obj = JSON.parse(httpRequest.responseText)
console.log(obj.V1, obj.V2, obj.V3, obj.V4);
var data = [],
time = (new Date()).getTime(),
i;
for (i = -60; i <= 0; i++) {
console.log(obj.V2)
data.push({
x: time + i * 60 * 1000,
y: obj.V2
});
}
myPopulation.series[1].data = data
// ???
console.log(data)
}
}
//here is my only addition
if(window.isLoaded){
onReadyFunction();
}else{
window.ajaxLoaded = true;
}
};
httpRequest.open('GET', "/myCall");
httpRequest.send();
}
So all I am doing is adding another part to the typical DOM load. Waiting for the data you need to be available before it initialized the rest of the JS. Doing this you can keep the least downtime for your app (although it depends on where you are trying to get this data though). All you need is to define the onReadyFunction like so.
function onReadyFunction(){
//all the rest of your JS here
}
This can be expanded and organized very easy, just a simple example to get started.

Ajax dojo request locking browser big json

I have a big json data about 40000 item. When I send request to get all, browser is locked process until responce come.
So I am sending request by index and chunk like following.
var index = 0;
var chunk = 500;
var repeat = true;
document.getElementById('loading').style.display='inline-block';
while (repeat == true) {
var requestOptions = {
handleAs: "json",
sync: true,
query: {
page: index,
chunk: chunk
},
};
request.get("domain.com/getdata", requestOptions).then(
function(response) {
array.forEach(response.data, function(item) {
//do something
});
if (response.data.length < chunk) {
repeat = false;
document.getElementById('loading').style.display='inline-block';
}
index = index + 1;
},
function(error) {
repeat = false;
}
);
}
I am sending request to get first 500 record. Than get secont 500 record...
When I sart process, the browser locking. I want to Show loading request but not appearing.
I see in the comments on your question that you've been recommended to use async:true, to which you respond that it is sending requests without getting any response, and always sending the same request parameters.
I think then that you're perhaps a bit unfamiliar with the asynchronous paradigm in Javascript (remember, Ajax means asynchronous Javascript and XML).
First off: async:true is the right way to solve your problem. However, as you've noticed, that alone doesn't fix anything in your code.
Here's a simplified and modified version of your code (don't try this, it doesn't work, it's for explanation purposes only).
var index = 0;
var chunk = 500;
var repeat = true;
while (repeat == true) {
var requestOptions = {
handleAs: "json",
sync: false, // false is default, so this line is redundant
query: { page: index, chunk: chunk },
};
request.get("domain.com/getdata", requestOptions).then(
responseOk, responseError);
}
function responseOk(response) {
//do something..
if (response.data.length < chunk) {
repeat = false;
}
index = index + 1;
}
function responseError(error) {
repeat = false;
}
Here's the kicker: the ´responseOk´ function is never run. Therefore, index is never updated, and repeat is never set to false - in effect making your while loop infinite!
Why is this? The reason is that Javascript's "Ajax" functions (which are wrapped by dojo's request.get() and friends) are asynchronous.
What you are saying in your code (or rather, in my simplified version above) is effectively:
Hey, Javascript, do a GET request to the server. When you are done,
sometime in the future, run this responseOk function (or responseError
on error). In the mean time, while you are doing that, I'll
continue with my while loop.
So the while loop keeps churning out GET requests to the server, with the same index! Since the neverending loop is keeping your Javascript thread busy (you only have one!), the responseOk function isn't allowed to execute (even though the server may have responded).
That said, how can you split your huge JSON array into multiple, subsequent requests?
You can try something like this:
var index = 0,
chunk = 500,
requestOptions = {....};
function handleResponseAndGetNextChunk(response) {
response && array.forEach(response.data, function(item) {
//do something
});
if(response && response.data.length < chunk) {
return;
} else {
requestOptions.page = index++;
request.get("domain.com/getdata", requestOptions).then(
handleResponseAndGetNextChunk, responseError);
}
}
// To start off the sequence of requests:
handleResponseAndGetNextChunk(null);

consecutive ajax calls freeze chrome and IE

i got a strange one. I have to make several consecutive ajax calls, and when a call is complete i update a progress bar. This works perfectly on FF but on the rest of the browsers what happens is that the screen freezes until all the calls are complete.
I am not executing the calls in a loop, but by using some sort of recursion cause there's a lot of checking that needs to be done and a loop is not convenient.
When i tried the same thing using a loop the outcome was more or less the same. Chrome or IE did not update the screen until all the ajax requests where done.
What i noticed is that it works ok on FF and opera, but chrome (safari too i suppose) and IE9 are behaving strange. Also on Chrome, during these requests, the response body of the previous request is empty and will remain like that until all requests are done.
Any ideas?
Code is extensive, but here goes. There is a wrapper to ajax, $(db).bind is a callback for success. db.records is the Json result. Model is an object holding several controller functions
$(db).bind('tokenComplete',function(){
var x = db.records;
if (!x.success) { model.callRollBack(); return false; }
var next = parseInt(x.get.num)+ 1;
if (typeof x.post.tokens[next] != 'undefined') {
model.executeToken(next,x.post);
}
else {
model.progressCurrent.find('div.report').html('all done!!');
}
});
model = {
drawProgressBarsTotal : function(el,i,v) {
var p = Math.floor(100 * i / versions.total);
el.find('span').html(p);
el.find('div.report').html('updating to : ' + v.version);
el.find('.changeLog').html(v.changeLog);
el.find('.changeLog').parents('div').show();
el.find('img').css({'background-position': 100 - p + '% 100%'});
},
executeToken : function(i,x) {
if (this.fail == true) { return; }
this.drawProgressBarsCurrent(this.progressCurrent,i+1,x);
db.trigger = 'tokenComplete';
db.data = x;
db.url = dbDefaults.url + '?num='+i+'&action='+x.tokens[i];//bring the first
$(db).loadStore(db);
}
}
loadStore :
$.dataStore = function( ds ) {
$.fn.loadStore = function(ds){
$.ajax({
type: ds.method,
url: ds.url,
data: ds.data,
dataType: ds.dataType,
cache:false,
async:true,
timeout:ds.timeout?ds.timeout:10000,
queue: "autocomplete",
contentType:'application/x-www-form-urlencoded;charset=utf-8',
accepts: {
xml: "application/xml, text/xml",
json: "application/json, text/json",
_default: "*/*"
},
beforeSend:function(){
loadStatus = true;
},
success: function(data) {
loadStatus = false;
if(data)
{ds.records=data;}
$(ds).trigger(ds.trigger);
},
error: function()
{
loadStatus = false;
$(ds).trigger('loadError');
}
});//END AJAX
};//END LOADSTORE
try {
return ds;
} finally {
ds = null;
}
}
}
Haven't followed your entire code, but it sounds like your problem may be related to continuous code execution. Typically the UI will not update during continuous code execution. To fix this, any call to a setTimeout() or any ajax calls should allow the browser time to update the UI. Basically, you must stop the code briefly, then start it again.
function updateUI () {
// change ui state
document.setTimeout( updateUI, 1 );
}
If I am off base here, let me know.

Dynamically append content to an element with jQuery

I would like to be able to have an ajax get update the text in a span tag each time it is fired.
$.ajax({
type: 'GET',
url: "JSON URL",
cache: false,
contentType: 'application/json',
dataType: 'json',
success: function(html){
$('#status_frame_span').prepend(html.status)
alert(html.status)
},
error: function(jq,stats,errmes) {
alert("Error" + errmes);
}
});
the first time it fires, the content of the json returned from the URL is properly prepended to the span. however for subsequent firings it is not updated.
How do I ensure that with each firing the content gets updated?
What triggers the call to the server? Is it a button or link inside of the HTML being updated? if it is, the event handler may be lost when the UI is updated. Or, something else is losing the event handler, which doesn't call the method to fire the get request, etc.
HTH.
Of course your view is updated only once: you are calling the server only once!
If, as your tags suggest, you are using long polling (please make sure that's the case, I'm not sure you have a very clear idea of what is an event, a poll and a distant call), then you need to make a new request each time you've received one!
In both your success and error handlers, you have to recursively make an AJAX call to the server. You also have to set a timeout for the calls, which could cancel them and start a new one after, for example, 30 seconds.
You should also implement some kind of throttling for recursive calls, unless you're 99.99% sure the server page will never send errors. Otherwise, you'll kill your client.
For the sake of completeness, I have to add this would be a great use-case for HTML5 SSE or WebSocket. But they're not ready for production usage yet.
it does not work that way - if the success callback is called - the connection has been closed so your long polling will be dead once the request is completed.
The idea behind long polling is that you keep the connection alive. Configure your server properly so that it will hold the connection open as long as possible (set timeout as high as possible).
Here's an approach from my coffee break (not tested):
Server
Every message has to end with the delimiter ::PART::
The server must be properly configured this means set the timeout as high as possible!
Client (Browser)
// setup longpoll, check all 250ms for new data in the stream
var myPoller = new LongPoll('some-url', 250);
// bind connection lost
myPoller.bind('longpoll:end', function(evt) {
alert('connection lost - trying reconnect');
});
// bind error event
myPoller.bind('longpoll:error', function(evt, errmsg) {
alert('error: ' + errmsg);
});
// bind data event
myPoller.bind('longpoll:data', function(evt, data) {
try {
// try to parse json
data = $.parseJSON(data);
// prepend
$('#status_frame_span').prepend(data.status);
} catch(e) {
// invalid json
alert('invalid json: ' + data);
}
});
longpoll.js
var LongPoll = function(url, timeout) {
// url we connect to
this.url = url;
// running?
this.isRunning = false;
// timer for checking the stream
this.timer = null;
// the length of the received data
this.dataLength = 0;
/*
The messages has to be delimited by the delimiter like:
first data::PART::second data::PART::third data::PART::
*/
this.delimiter = RegExp.new("::PART::", 'gm');
// residue from previous transmission
this.residue = ''
};
// connect to server
LongPoll.prototype.connect = function() {
var self = this;
// reset data length
this.dataLength = 0;
// reset residue
this.residue = '';
// start ajax request
this.xhr = $.ajax({
type: 'GET',
url: this.url,
cache: false,
contentType: 'application/json',
dataType: 'text',
success: function(){
// the connection is dead!
self.xhr = null;
// trigger event
$(self).trigger('longpoll:end');
// reconnect if still running
if(self.isRunning) {
self.connect();
}
},
error: function(jq,stats,errmes) {
// stop timer and connection
self.stop();
$(self).trigger('longpoll:error', errmes);
}
});
};
// process data
LongPoll.prototype.process = function(buffer) {
var self = this;
// check if there is anything new
if(buffer.length > this.dataLength) {
var newData = this.residue + buffer.substring(this.dataLength, buffer.length);
// reset residue
this.residue = '';
// store the new position
this.dataLength = buffer.length;
// split data
var dataParts = newData.split(this.delimiter);
// how many full parts?
var fullParts = newData.match(this.delimiter).length;
if(dataParts.length > fullParts) {
// pop residue (incomplete message)
this.residue += dataParts.pop();
}
$.each(dataParts, function(index, part) {
// broadcast data parts
$(self).trigger('longpoll:data', $.trim(data));
});
}
};
// check for data
LongPoll.prototype.receive = function() {
var self = this;
// connection still there?
if(this.xhr) {
// process buffer
this.process(this.xhr.responseText);
}
};
// start long poll
LongPoll.prototype.start = function() {
var self = this;
// set flag
this.isRunning = true;
this.timer = setInterval(function() { self.receive(); }, this.timeout);
this.connect();
};
// stop long poll
LongPoll.prototype.stop = function() {
// set flag
this.isRunning = false;
// clear timer
clearInterval(this.timer);
if(this.xhr) {
// abort request
this.xhr.abort();
}
};

Categories