我有一个for
循环,我在其中调用一个函数。此函数发出HTTP请求并通过回调提供对象。然而,在for
循环中,我尝试将index
与闭包绑定。但它不起作用。 index
似乎总是一样的。我的代码出了什么问题?
for(var y = 0; y < caps.length; y++) {
(function(index) {
getChildContent(caps[index], function(content) {
var child = {};
child.FunctionName = caps[index];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content);
});
})(y);
}
@treeno这是getChildContent函数:
function getChildContent (capname, callback) {
t = capname.replace(' ', '_');
bot.page(t).complete(function (title, text, date) {
var str = S(text).between('== Kurzbeschreibung ==\n* ', '.').s;
if(str === undefined || str === null || str === '') {
throw new Error('Undefined, Null or Empty!');
}
else {
var content = {};
str = parseTitles(str);
content.Owner = str[0];
content.Aim = str[1];
content.What = str[2];
content.Who = str[3];
content.Steps = str[4];
content.Page = 'someURL';
callback(content);
}
});
}
答案 0 :(得分:1)
索引没问题,
ajax响应时间是不同的,所以它不会按顺序
像这样:function getChildContent (capname, callback) {
// simulate ajax call with random response time
setTimeout( function () {
var content='pizza';
callback(content);
}, (Math.random(0,1000)*1000));
}
var parent = { Functions: [] };
var caps = ['lol', 'lol2', 'haha'];
for(var y = 0; y < caps.length; y++) {
(function(index) {
console.log(index);
getChildContent(caps[index], function(content) {
var child = {};
child.FunctionName = caps[index];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content, index, caps[index]);
});
})(y);
}
// Outputs:
// These are the indexes (Yes, they are in order)
// 0
// 1
// 2
// These are the responses (The order is based from the request completion time)
// pizza 1 lol2
// pizza 2 haha
// pizza 0 lol
[更新]
有一种方法可以按照你想要的方式进行,但它会等到所有的回复都完成。
function waitLoadCompleted( callback ) {
if( loaded == caps.length ) {
// do stuff
callback( );
}
}
function getChildContent (capname, callback) {
// simulate ajax call with random response time
setTimeout( function () {
var content='pizza';
callback(content);
}, (Math.random(0,1000)*1000));
}
var loaded = 0;
var tempcontainer = [];
var parent = { Functions: [] };
var caps = ['lol', 'lol2', 'haha'];
for(var y = 0; y < caps.length; y++) {
(function(index) {
console.log(index);
getChildContent(caps[index], function(content) {
loaded++;
tempcontainer.push({ index: index, data: content });
waitLoadCompleted(function(){
// everything is loaded
tempcontainer.sort(function(a, b) { return a.index - b.index; });
for( i in tempcontainer ) {
var index = tempcontainer[i].index;
var child = {};
child.FunctionName = caps[index];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content, index, caps[index]);
}
})
});
})(y);
}
// Outputs:
// 0
// 1
// 2
// pizza 0 lol
// pizza 1 lol2
// pizza 2 haha
[UPDATE]
另一种解决方案是将其细分为一组响应,并通过对收集的响应进行排序,使其看起来像顺序 例如。比如FB帖子,聊天等等,答案永远不会结束
function getChildContent (capname, callback) {
// simulate ajax call with random response time
setTimeout( function () {
var content='pizza';
callback(content);
}, (Math.random(0,1000)*1000));
}
var tempcontainer = [];
var parent = { Functions: [] };
var caps = ['lol', 'lol2', 'haha'];
for(var y = 0; y < caps.length; y++) {
(function(index) {
console.log(index);
getChildContent(caps[index], function(content) {
tempcontainer.push({ index: index, data: content });
tempcontainer.sort(function(a, b) { return a.index - b.index; });
for( i in tempcontainer ) {
var child = {};
child.FunctionName = caps[index];
child.Content = [];
child.Content.push(content);
parent.Functions.push(child);
console.log(content, tempcontainer[i].index, caps[tempcontainer[i].index]);
}
console.log("<--SET RESPONSE-->");
});
})(y);
}
// Outputs:
// 0
// 1
// 2
// pizza 1 lol2
// <--SET RESPONSE-->
// pizza 0 lol
// pizza 1 lol2
// <--SET RESPONSE-->
// pizza 0 lol
// pizza 1 lol2
// pizza 2 haha
// <--SET RESPONSE-->