javascript worker loop ajax - javascript

I am having a worker which has an array of urls. I loop through these URLs and throw an AJAX call, but inside success method of ajax when I send message back to website, it always sends the last request.
app.js
var worker = new Worker('worker.js');
var urls = ['url1','url2','url3'];
worker.addEventListener('message', function(e) {
console.log('Worker: ', e.data.url);
}, false);
worker.postMessage({"args":[urls]});
worker.js
self.addEventListener('message', function(e) {
function load(url){
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
console.log(xmlhttp);
self.postMessage({'url':url});
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
var urls = e.data.args[0];
for(var i = 0; i<urls.length; i++){
load(urls[i]);
}
}, false);
Now inside console.log(); of app.js, the output is only of the last url.
I don't get all all URLs response.
Can anyone help ?

The answer is real easy. make line 3
var xmlhttp=new XMLHttpRequest();
What you're doing now, is setting xmlhttp as a global variable. This means overriding the variable every time line 3 is executed.

Related

Variable does not work outside of function

I have a function that loads a JSON file and gives it to a variable called articles. When i log articles inside of the function, it shows my json file, but when i log it outside of my function it doesn't show anything at all
I have tried to use let and var before articles inside of the function but that doesn't seem to work
var articles = ""
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
articles = xmlhttp.responseText;
console.log(articles);
}
};
console.log(articles);
console.log(xmlhttp);
xmlhttp.open("GET","articles.json",true);
xmlhttp.send();
I want to be able to call my json file outside of my function by using articles, so that i don't have ot type xml.responseText each time.
In short, JavaScript does not synchronously wait for I/O operations to finish (network call in this case).
What this means is that when you log articles "outside of the function", the articles variable has not yet been set (the http request has not been completed).
Why are you hoping to have access to articles globally?
You could optionally pass your articles into a processing method after the http request has responded like so:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
var articles = xmlhttp.responseText;
processArticles(articles)
}
};
xmlhttp.open("GET","articles.json",true);
xmlhttp.send();
function processArticles(articles) {
// Do something with articles here
}

xmlhttp.open multiple XML files

How would I go about fetching multiple XML files? I tried creating an array but that only opens the last file, and as I understand it xmlhttp.open is supposed to cancel any previous send. I tried modifying this which was the closest thing I could find, but my JavaScript knowledge is a bit to limited to adapt it.
This is the basic code I'm using to get one XML file.
if (window.XMLHttpRequest)
{ xmlhttp=new XMLHttpRequest();
}
xmlhttp.open("GET","myfile.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
var x=xmlDoc.getElementsByTagName("TAGNAME");
for (i=0;i<x.length;i++)
{ // Further parsing
}
Also is it possible to then display which file the parsed content comes from in my loop?
try this:
var arr = ["file1.xml", "file2.xml"],
cnt = 0, xhr = new XMLHttpRequest(), method = "GET";
function formatXml(file, xmlDoc) {
var x=xmlDoc.getElementsByTagName("TAGNAME");
console.log(file,x);
}
function getXml() {
xhr.open(method, arr[cnt], true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
formatXml(arr[cnt], xhr.responseText);
cnt++;
if (cnt < arr.length) getXml(); // call again
}
};
xhr.send();
}
getXml(); // start it

Second request receives the first one that was still processing

I have a request system where two unrelated functions are making requests to my server. But the problem is the response is not correct let me explain what is happening step by step:
A background function makes a request to the server
Server processes task 1
A second unrelated background function makes a request to the server
Client recieves response of task 1
The second function recieves that response that was for the first function.
The first function never gets a response.
Now i don't know how to solve it, but i know i need to distinguish them separately so theres no conflictions here.
This is my current code that handles the request stuff:
function call_back(result,func){
if(typeof(func) != 'undefined' || func != false){
func(result);
} else {
return false;
}
}
function caller(url,cfunc){
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function call_file(url,func){ //handles html files (not json_encoded)
caller(url,function(){
if ( xmlhttp.readyState== 4 && xmlhttp.status== 200 ){
call_back(xmlhttp.responseText,func);
}
});
}
function call_data(url,func,JsonBool){ //handles json_encoded data
caller(url,function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
call_back(JSON.parse(xmlhttp.responseText),func);
}
});
}
What can i do to my functions, for preventing this behaviour?
Here is an example of how you could structure your code - I have used this, it works, but it could be refined.
function Ajax(url, callback,args){
var xhttp = init();
xhttp.onreadystatechange = process;
function init() {
if(window.XMLHttpRequest)
return new XMLHttpRequest();
else if (window.ActiveXObject)
return new ActiveXObject("Microsoft.XMLHTTP");
}
function process() {
if (xhttp.readyState==4 && xhttp.status==200) {
if (callback) callback(xhttp.responseText,args);
else return xhttp.responseText;
}
}
this.Get=function(){
xhttp.open("GET", url, true);
xhttp.send(null);
}
}
To use it:
var url = '/someurl';
var ajax = new Ajax(url,yourCallback,parameters);
ajax.Get();
I believe DRobinson was talking about something like this but more robust. This should be a good example to get you started though.
It looks to me as though you're using a global/window variable for xmlhttp. If this is the case, certain parts of the second call will overwrite the first. Consider using an Object Oriented approach, or otherwise instantiating these as vars in different scopes.

How to do a request to the server and liberate JavaScript to continue processing

Is there a way to make a request and liberate JavaScript and HTML to do their own thing, leaving the Server to do its thing until it completes, at which point an event grabs control of JavaScript, dumps the data to a designated receiving end and ends the call?
I use this method for calling Python
function par_makeHttpObject() {
try {
return new XMLHttpRequest();
}
catch (error) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP");
}
catch (error) {}
try {
return new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error) {}
throw new Error("Could not create HTTP request object.");
}
And I call it as follows:
...
var request = par_makeHttpObject();
request.open("POST", "../getFdList?Fds=allFds", false);
request.send();
var dta = request.responseText.split("\n");
var cnt = 0;
for (var x in dta) {
try {eval(dta[x]);}
catch (error) {alert("JS Error - check JS part of syntax!\n" + dta[x]);}
}
...
The problem is that JavaScript sits and waits for a reply to the request and the user could be doing something else. Some calls take 5 minutes...
Any ideas would be appreciated.
DK
Use jQuery's ajax() function instead of rolling your own AJAX solution. ajax() defaults to asynchronous requests, so you can pass it a function that is called on request completion:
$.ajax({
type: "POST",
url: "../getFdList?Fds=allFds"
}).done(function( msg ) {
alert( "Response: " + msg );
});
That way, you can call ajax(), give it your callback function, and carry on with whatever other processing you need to do.
Another plus for jQuery is that it's pretty well cross-browser without any effort.
Yes, it's very easy in fact. Change the last parameter in your open call to "true":
(I pulled this from w3schools(Yes I'm aware of the sites bad rep, this is just an example))
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//THIS IS WHERE YOU GET THE SERVER RESPONSE
var response = xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
}
The best part about AJAX is the ability to continue working on something else while the HTTP request is being made asynchronously.
$.post('../getFdList?Fds=allFds', {}, function(response) {
var dta = response.split("\n");
// ...
}, 'text');
// continue doing something else here
See also: $.post()

AJAX/ Javascript - Pass contents of txt file into Javascript variable

I'm trying to read a list of words from a txt file into a Javascript variable to use later in my script. However, I am unable to pass the variable out of the onreadystatechange function. Is there some simple step that I'm missing?
Source:
var xmlhttp;
var list = new Array();
var word;
if (window.XMLHttpRequest) xmlhttp=new XMLHttpRequest();
else xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
list = xmlhttp.responseText.split("\n");
document.getElementById("testfield").innerHTML = list[0]; //This works
word = list[0];
}
}
xmlhttp.open("GET","wordlist.txt",true);
xmlhttp.send();
document.getElementById("testfield").innerHTML = word; //This doesn't work
The problem is that this code
document.getElementById("testfield").innerHTML = word; //This doesn't work
is being run before your xhr callback. As a result, word is undefined
This xmlhttp.send(); is sending off your ajax request, and then returning immediately. Your code then proceeds to
document.getElementById("testfield").innerHTML = word;
where word is still undefined, then, some time later, your ajax request completes, your callback is called, and word is set to the result too late for your to care.

Categories

Resources