2015-10-17 55 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

什麼是你的數據在做什麼?如果順序執行每個步驟很重要,那麼同步循環可能會更好。讓我知道這個解決方案(等待所有的回報然後重新排序)不適合你,我會告訴你我的解決方案,我用它來順序地執行這些事情,以防需要做計算等。 ,乍看之下,根據使用情況,我沒有發現這個解決方案有什麼問題。 –