2015-10-17 57 views
0

循环我有一个for回路,其中我调用一个函数。该函数发出一个HTTP请求并通过回调提供一个对象。然而,在for循环中,我尝试将index与闭包绑定。但它不起作用。 index似乎总是相同的。我的代码有什么问题?封闭在用于与HTTP请求

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); 
     } 
}); 

}

+2

你如何检查是否'index'是相同的(如在它的面前,这个代码似乎是正确的)?如果你在另一个'console.log'旁边添加一个'console.log(index)',你是否看到相同的'index'? –

+1

你也可以显示getChildContent()吗?也许它总是存储传递函数在同一个对象,那么,你覆盖在每个迭代函数...所以你总是与最后一个函数结束了......只是一个猜测... – treeno

+0

@treeno我编辑的OP和添加的getChildContent()函数 – dnks23

回答

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]

另一个解决方案是段到一个组的响应和使它看起来像everthings为了通过排序所收集的响应 例如像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--> 
+0

感谢您的努力!很高兴知道该代码是好的...但是有没有办法让所有东西都按顺序? – dnks23

+0

是有,我用这个做一个装载游戏与它们相比,更新后... – PauAI

+0

什么是你的数据在做什么?如果顺序执行每个步骤很重要,那么同步循环可能会更好。让我知道这个解决方案(等待所有的回报然后重新排序)不适合你,我会告诉你我的解决方案,我用它来顺序地执行这些事情,以防需要做计算等。 ,乍看之下,根据使用情况,我没有发现这个解决方案有什么问题。 –