1

这是我的问题的描述:

我有一个数组,其中包含一些 flickr 照片集的 id。对于每个 id,我需要制作两个嵌套的 apiCalls(一个到 flickr photoset api,一个到 photoinfo api)并将一些 html 添加到我的页面

结构是:

for(var i=0; i<ARRAY_ID.length; i++){

    $.getJSON(apiCall, function(data) {
         // some processing here

         $.getJSON(apiCall2,function(data){
              //other processing here

每个“apiCall”都是一个字符串,其中包含对照片集 api (apiCall) 的正确调用,然后是对 photoInfo api (apiCall2) 的正确调用

在所有这些处理之后,在“apiCall2”块内,我将一些 html 附加到一个 div (这导致与 ARRAY_ID 长度一样多的块元素)。

我有奇怪的行为:所有附加的块元素都包含相同的文本、图片和链接。它以预期的数量将它们打印出来,但它们的内容都是相同的。我猜这是 for 循环不等待 $.getJSON 完成。我怎样才能做到这一点?我严格要求在处理下一个请求之前完成每个 json 请求!谢谢大家!

4

3 回答 3

4

您似乎有 2 个不同但相关的问题。


所有附加的块元素都包含相同的文本、图片和链接。它以预期的数量将它们打印出来,但它们的内容都是相同的。

如果您在i回调中引用,则需要将其包含在for. 否则,由于$.getJSON是异步的,for将在调用回调之前完成,并且i始终是循环中的最后一个值 -- ARRAY_ID.length

for(var i = 0; i < ARRAY_ID.length; i++) {
    (function (i) {
        // work with the local `i` rather than the shared `i` from the loop
    })(i);
}

我猜这是 for 循环不等待 $.getJSON 完成。我怎样才能做到这一点?我严格要求在处理下一个请求之前完成每个 json 请求!

你不能让for每组都“等待”$.getJSON完成。但是,您可以使用for循环和闭包来构建一个queue,它会一直等待,直到您明确告诉它next继续:

var focus = $(...); // either match an existing element or create one: '<div />'

for(var i = 0; i < ARRAY_ID.length; i++) {
    (function (i) {
        focus.queue('apicalls', function (next) {
            $.getJSON(apiCall, function(data) {
                 // some processing here

                 $.getJSON(apiCall2,function(data){
                      //other processing here

                      next(); // start the next set of api calls
                 });
            });
        });
    })(i);
}

focus.dequeue('apicalls');
于 2012-04-23T20:36:37.653 回答
1

这是闭包的常见问题。您的回调从包含 for 循环的函数的上下文中继承变量(我将其称为主函数)。试试这个:

for(var i=0; i<ARRAY_ID.length; i++){

    $.getJSON(apiCall, (function(i, v1, v2, etc) { return function(data) {
        // some processing here


        $.getJSON(apiCall2,function(data){
        //other processing here
    })(i, v2, v3, etc));
}

基本上,现在您正在更改闭包从中访问变量的上下文。您创建一个匿名函数并传递您从主函数访问的所有变量。在示例中,我传递了变量 i,而 v1、v2 等表示您可能正在访问的其他变量。

通过为每个闭包调用创建正确的上下文,您应该能够解决这个问题。

于 2012-04-23T20:31:36.830 回答
1

很可能是范围问题。

如果您传递给 getJSON 方法的回调使用i循环的变量,那么它们很可能都使用i.

解决方案是

function handleJsonRequests(index,id){
 // use index instead of i
 // use id instead of ARRAY_ID[i]

 $.getJSON(apiCall, function(data) {
         // some processing here

         $.getJSON(apiCall2,function(data){
              //other processing here

}// end of function

for(var i=0; i<ARRAY_ID.length; i++){
    handleJsonRequests(i, ARRAY_ID[i]);
}
于 2012-04-23T20:32:08.873 回答