使用HTTP请求关闭for循环

时间:2015-10-17 09:27:02

标签: javascript loops asynchronous callback closures

我有一个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);
        }
});

}

1 个答案:

答案 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-->