2013-10-03 3 views
8

После нескольких часов поиска у меня есть проблема с моим кодом Ниже. На самом деле, я не очень далек от ответа. Я думаю, но я все еще заблокирован ...Javascript: анонимная функция, доступ к глобальным переменным

У меня есть анонимная функция, называемая внутри цикла, и я хочу получить доступ и обновить глобальные переменные, но я попробовал с помощью window.myvariable , с другой функцией и ничего случиться ...

это мой код:

for (var i = 0; i < SHP_files.length; i++) { 
      shapefile = new Shapefile({ 
       shp: "shp/polygon/"+SHP_files[i]+".shp", 
       dbf: "shp/polygon/"+SHP_files[i]+".dbf", 
       }, function(data) { 

        polygon_layer.addLayer(new L.GeoJSON(data.geojson,{onEachFeature: onEachFeature, style: polygonStyle})); 
        polygon_layer.addTo(map); 
        console.log(polygon_layer.getLayers()); // IS OK 
       }); 
     }; 
     console.log(polygon_layer.getLayers()); // IS EMPTY !! 

Итак, как я мог бы превратить эту анонимную функцию, чтобы иметь что-то, что я могу получить доступ из моего кода, который следующее что?

Большое спасибо, и извините за мой английский не очень хорошо ...

+0

сделать некоторые исследования по асинхронным (без блокировки) кодирования модели. – user2736012

+0

Я не совсем понимаю ваш вопрос, что я вижу здесь, вы передали функцию в качестве аргумента. Вы уверены, что он вызван в конструкторе? –

+0

Что делает 'новый Shapefile()' do? Если он загружает файлы '.shp' и' .dbf' через AJAX, а функция - обратный вызов успеха, загрузка может происходить асинхронно. ("на заднем фоне"). Это означает, что после окончания цикла файлы будут загружаться только, они будут добавлены позже в 'polygon_layer'. – millimoose

ответ

4

Это типичная проблема с выполнением асинхронного кода. Код примера не выполняется сверху вниз. В частности, ваша анонимная функция НЕ запускается до тех пор, пока Shapefile не будет выполнен с тем, что он делает. Тем временем ваш JS будет выполнен в порядке. Поэтому последняя строка вашего вышеуказанного кода будет , вероятно, выполнить перед анонимной функцией.

Чтобы это исправить, вам нужно будет запускать любой код, который зависит от Shapefile ответа изнутри его функции обратного вызова:

for (var i = 0; i < SHP_files.length; i++) { 
    shapefile = new Shapefile({ 
     shp: "shp/polygon/"+SHP_files[i]+".shp", 
     dbf: "shp/polygon/"+SHP_files[i]+".dbf", 
     }, function(data) { 
      polygon_layer.addLayer(new L.GeoJSON(data.geojson,{onEachFeature: onEachFeature, style: polygonStyle})); 
      polygon_layer.addTo(map); 
      executeMoreCode(); 
     }); 
}; 

function executeMoreCode() { 
    console.log(polygon_layer.getLayers()); // IS OK 
} 
+0

* «... вероятно, будет выполняться перед анонимной функцией ...» * должен читать * «... обязательно выполнит ...» *. Поскольку среда является однопоточной, любой асинхронный код (например, обратные вызовы) должен ждать, пока поток будет доступен, что означает, что 'console.log()' внизу будет всегда выполняться первым. – user2736012

+0

Ну, я вижу вашу точку зрения, но я нарочно сказал * вероятно *, потому что это правда. Поскольку асинхронный вызов происходит в цикле, я не знаю, сколько циклов выполнения он занимает. Если мы говорим о 100 или 200 итерациях, есть хорошая вероятность, что первый асинхронный вызов возвращается до выхода цикла. Поэтому в этот момент массив 'polygon_layer' больше не может быть пустым. Но вы правы в том, что он определенно * не будет иметь ВСЕ данные. – Steve

+0

Собственно, нет. Поскольку сам цикл (за которым следует вызов 'console.log()'), является синхронным, он блокирует любую асинхронную активность до тех пор, пока она не будет завершена. Так что преувеличивайте ситуацию, когда цикл 'for' занимает 1 секунду.Если первый обратный вызов будет готов только через 100 миллисекунд, он все равно не будет вызван, потому что цикл 'for' (а затем' console.log() ') заблокирует его. Асинхронный код всегда должен ждать завершения текущего кода синхронизации. – user2736012

2

Попробуйте определения переменные, в этом случае polygon_layer, вне для цикла или функции. См. Следующий пример:

var f; 
for(var i=0; i<5;i++){ 
    (function(){ 
     f = 10; 
     console.log(f); // Outputs 10 
    })(); 
} 
console.log(f); // Also outputs 10 
+0

Я очень сомневаюсь, что это причина проблемы. Он/она, вероятно, уже имеет 'polygon_layer', определенный вне цикла (а если нет, это будет просто глобальная переменная). Проблема, скорее всего, заключается в асинхронном характере вызова «Shapefile». – Steve

+0

Скорее всего, это просто попытка сначала решить самое легкое решение. –

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