Reputation: 1097
I'm getting this little trouble while looping, I always get the same "y" value (5) and it doesn't decreases or increases. What I want is to repeat the ajax call X times [all] and pass the response and the current call number thru an anonymous function. I hope you can help me.
function _shds(long, count, func) {
for (var y = 0; y < count; y++) {
gapi.client.load('urlshortener', 'v1', function() {
var request = gapi.client.urlshortener.url.insert({
'resource': {
'longUrl': long
}
});
var resp = request.execute(function(resp) {
func(resp.id, y);
});
});
}
}
var total = 3;
var base = "soem";
var lista = ["1", "2", "3", "4", "5"];
_shds("222", total, function(data, y) {
if (data != "undefined") {
newbase = base.replace("soem", data);
console.log(lista[y].uid + newbase + " pos:" + y);
}
});
UPDATE: Sorry, here's an example of the code: http://jsfiddle.net/ZgXZB/
Upvotes: 1
Views: 2181
Reputation: 134167
This is a trickier problem than it first appears, and a common JavaScript gotcha. What is going on is that when you say:
for (var y = 0; y < count; y++) {
gapi.client.load('urlshortener', 'v1', function() {
var request = gapi.client.urlshortener.url.insert({
'resource': {
'longUrl': long
}
});
var resp = request.execute(function(resp) {
func(resp.id, y);
});
});
}
You are creating a closure on y
in the function callback that you pass to get
. However, you only have created one closure and it has the final value of y
which is count
. What you want to do is create count
different closures, so you need to introduce a new scope:
for (var y = 0; y < count; y++) {
(function (y){
gapi.client.load('urlshortener', 'v1', function() {
var request = gapi.client.urlshortener.url.insert({
'resource': {
'longUrl': longurl
}
});
var resp = request.execute(function(resp) {
func(resp.id, y);
});
});
})(y);
}
I believe that should do it. You need to declare a new function to create a new scope in JavaScript, and by passing y
as a parameter to that function you are creating a new closure for each value of y
.
Upvotes: 4
Reputation:
The issue is that you are trying to get the value of i
after the callbacks have returned, which is after your for-loop has finished. What you need to do is bind
the value of i
you want to pass to the callback when you first construct your intermediate callback for $.get
:
function _short(longurl, count, func) {
for (var y = 0; y < count; y++) {
gapi.client.load('urlshortener', 'v1', function() {
var request = gapi.client.urlshortener.url.insert({
'resource': {
'longUrl': longurl
}
});
var resp = request.execute((function(y, resp) {
func(resp.id, y);
}).bind(this, y));
});
}
}
var totalchat = 10;
var base = "soem";
var listachat = ["1", "2", "3", "4", "5"];
_short("222", 3, function(data, y) {
if (data != "undefined") {
newbase = base.replace("soem", data);
console.log(listachat[y].uid + newbase + " pos:" + y);
}
});
What bind
does is create a new function where the value of this
is bound to the first parameter (which I just set as this
) and all remaining arguments are bound to the first arguments of the function, while the function it returns takes a new set of arguments (in this case, only the data
argument remains from the original function, which matches the callback signature of $.get
).
Upvotes: 2