2017-01-19 88 views
0

我有如下的数组。用于循环的异步ajax处理的Javascript关闭

var clients = ['a','b']; 
var reports = ['x','y','z']; 
var finalData = []; 

现在我需要像这样循环。

for(var i=0;i<reports.length;i++){ 
    var response = {report : reports[i]} 
    for(var j=0;j<clients;j++){ 
     response.client = clients[i]; 
     $.ajax({ 
     url :url, 
     success : function(data){ 
      response.data = data; 
      finalData.push(response); 
     }) 
    }); 
    } 
} 

由于ajax是异步的,所以它不能正常工作。 另外我需要将它包装到react.js componentDidMount函数中,并将finalData推入状态。

我试图$.each而不是for循环和.bind(this)将最终数据推入状态。但我没有得到正确的数据。我听说异步调用应该使用闭包,但没有得到如何在这里实现。 我正在寻找的输出是。

finalData = [ 
     {client:a,report:x,data : 'xyz'}, 
     {client:b,report:x,data : 'xyz'}, 
     {client:a,report:y,data : 'xyz'}, 
     {client:b,report:y,data : 'xyz'}, 
     {client:a,report:z,data : 'xyz'}, 
     {client:b,report:z,data : 'xyz'} 
    ] 
+1

你可以使用封闭保存报表和客户创造价值看到更多的细节http://stackoverflow.com/questions/6077357/passing-index-from-for-loop-to-ajax-callback-function-javascript –

+0

您的示例代码中有多个编码错误。例如'客户[我]'应该是'客户[j]'。 –

回答

0

你要保存的范围(使用colsure)为您的响应变量,请尝试以下操作:

for(var i=0;i<reports.length;i++){ 
    var response = {report : reports[i]} 
    for(var j=0;j<clients;j++){ 
     response.client = clients[i]; 

     (function(responce){ 
     $.ajax({ 
     url :url, 
     success : function(data){ 
      response.data = data; 
      finalData.push(response); 
     }) 
     })(responce); 

    }); 
    } 
} 

让更多解释,模拟阿贾克斯将在这里的例子使用setTimeout

让我们来看看这个例子中,它是一个循环5次,一秒钟后,将需要打印i我们期待打印0 1 2 3 4,但实际上它会打印5的5倍,因为在1日前循环结束秒消耗,然后当它海RCH为我打印我在这种情况下= 5

for(var i=0;i<5;i++){ 
    setTimeout(function(){ 
    console.log(i); 
    console.log("...."); 
    }, 1000) 
} 

和解决,这将需要有一个范围,以节省i值,所以当超时完成,它可以找到正确的i值被称为关闭:

for(var i=0;i<5;i++){ 
    (function(i){ 
    setTimeout(function(){ 
     console.log(i); 
     console.log("...."); 
    }, 1000) 
    })(i); 
} 

此代码将按预期工作将打印0 1 2 3 4正确,这就是你的例子所做的。

,并更新你可以每次更新的状态,你收到一个值:

var that = this; // to be added in top of the 2 for loops 
finalData.push(response); 
this.setState({data: finalData}) 

,或者你可以检查是否加载所有客户端的所有报告,然后更新状态:

// total can be calculated by num of reports X number of clients 
if(finalData.length == total){ 
    this.setState({data: finalData}) 
}