2012-08-05 22 views
1
function updateRoomsList() { 
    //empty the rooms list 
    $("#rooms").empty(); 
    //fetch the non-joined rooms, id and name 
    $.get('JoinPart', { 
     goal: 5, 
     userName: $("#userName").html() 
    }, function (responseText) { 
     var i = 0; 
     id = ""; 
     while (i < responseText.length) { 
      if (responseText.charAt(i) == '.') { 
       //Now we got the full Id of a room, lets add it 
       $.get('JoinPart', { 
        goal: 6, 
        roomId: id 
       }, function (responseText) { 
        roomName = responseText; 
        $("#rooms").append('<div id="room' + id + '" class="listItem"><span title="Join Room" class="joinButton">+</span><div class="listItemContent">' + roomName + '</div></div>'); 
       }); 
       id = ""; 
      } else { 
       id = id + responseText.charAt(i); 
      } 
      i++; 
     } 
    }); 
} 

在函數訪問變量的函數內。在該函數有一個變量id,如果我alert(id);不能在JavaScript

if(responseText.charAt(i)=='.') 

我得到的ID在else計算出正確的值,但是當我在做alert(id);裏面的$.get這個id是空的"",意思是在append函數中,id沒有任何值,我怎麼能得到這個id值超出$ .get函數的值?

+0

您是否嘗試過聲明ID您updateRoomsList功能之外,您可以測試:'VAR ID;' – j08691 2012-08-05 15:40:59

回答

1

這是因爲id在外部封閉範圍的,所以你內在的回調到達它的設置在while循環結束的最後一個值的參考。如果您需要第二$.get()回調內部id變量的專用副本,你需要寫

$.get('JoinPart', {goal :6, roomId :id }, (function (id) { 
    return function (responseText) { 
    roomName = responseText; 
    $("#rooms").append('<div>' + id + '</div>'); 
    } 
})(id)); 

當你這樣做,你創建一個新的範圍與被給出的精確值id有一個局部變量id在當前迭代,而不是局部變量id本身,這在循環結束(或者真的只是下一輪迭代)可以是任何東西。

構造(function(arg){})(arg)被稱爲immediately invoked function expression。請注意,這個函數返回一個新的函數對象,通過$.get()

要求之一的封閉裏面另外一個定義的函數。閉包,顧名思義,可以訪問本地外部函數的變量。當您爲以後執行到$.get()回調,你實際上是使用一個封閉:回調時將被執行(可能幾秒鐘後)JS引擎將使id仍然可以訪問,但其價值顯然取決於的休息碼。

如果你需要存儲變量的當前快照供日後閱讀,你需要創建一個新的閉包(即一個新的範圍):我們用IIFE用於此目的。IIFE執行正確之前實際的HTTP請求被激發(即之前$.get()甚至被稱爲),它是最接近的回調範圍,所以它將用於解決id引用時回調將是執行。

如果你瞭解搞清楚什麼概念以下代碼將打印

function inner() { 
    console.log(i);   
} 

for (var i = 0; i < 3; i++) { 
    inner(); 
    setTimeout(inner, 1000); 
}​ 
+0

OMG它的工作!非常感謝:D我喜歡包含我的代碼的固定版本的答案,讓我的一天好多了,我愛你男人:D – 2012-08-05 16:19:31

1

碼流是不是你認爲的順序。

  id=""; 

是功能中之功能,這被稱爲閉合前發生的事情,對了(這應該在谷歌上搜索幫助)。添加打印語句

alert("here 1"); 
alert("here 2"); 

在封閉和id="";之前,這應該跳出。

最簡單的解決可能是在封閉與roomId交換id,因爲,作爲一個簡單的字符串或者int值被完全複製到roomId,在那裏將是安全的,即使id改變(好吧,更準確,id=...因此通過roomId所指的價值保持不變只改變參考。)