2012-08-05 4 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)=='.') 

я получить правильное значение идентификатора рассчитывается в else, но когда я делаю alert(id); внутри $.get, идентификатор пуст "", означает в функции append, id не имеет значения, как я могу получить этот идентификатор, чтобы иметь значение вне функции $ .get?

+0

Вы пытались объявить идентификатор за пределами вашей функции updateRoomsList: 'уаг идентификатор,' – j08691

ответ

1

это потому, что id является областью действия во внешнем замыкании, так что ваш внутренний обратный вызов получает ссылку на последнее значение он установлен в конце цикла while , Если вам нужен частный экземпляр переменной id внутри второго $.get() обратного вызова, вам нужно написать

$.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()

A Закрытие - это функция, определенная внутри другой. Закрытие, по определению, может обращаться ко всем переменным, локальным к внешней функции. Когда вы отправляете обратный вызов для последующего выполнения на $.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 –

1

Кодовый поток не соответствует вашему порядку.

  id=""; 

происходит перед функцией-внутри-функцией, которая называется замыканием, кстати (это должно помочь в вашей прибегая к помощи). Добавьте операторы печати

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

в крышке, и перед id=""; и это должно выскочить.

Самый простой исправление возможно поменять id с roomId в замыкании, так как, будучи простой строки или междунар значение полностью копируется в roomId, где он будет в безопасности, даже если id изменения (ок, более точно, id=... изменяет только ссылку, так что значение ссылается roomId остается такой же.)

Смежные вопросы