2013-11-11 7 views
0

Я пытаюсь не копировать код и не перебирать функцию a в асинхронном режиме d3. Вот кодАсинхронная функция в итерации - javascript

Поскольку d3.text является асинхронным, я не могу правильно использовать индекс u для добавления объектов в DOM. Как мне это сделать? Мне нужен цикл, чтобы перейти к следующей итерации однажды d3.text закончил

for(var u in urls) { 
    console.log(u); 
    var url = "interest_points/" + urls[u] + ".csv"; 
    var data_gpBy_month = {}; 
    var sortable_month = [] 

    d3.text(url, function(text) { 
    // some code... 
    var data = d3.csv.parseRows(text).map(function(row) { 
     //some code...   
    }); 

    //some code 
    });   
} 
+0

Почему бы не захватить значение и в анонимной функции , затем передать захваченное значение в качестве параметра во внутреннюю функцию? То есть, захватите индекс var на внешнем закрытии и передайте его чисто на внутреннее закрытие? –

+0

Да, это похоже на то, что @DavidW предлагает правильный подход (в отличие от любого из нижеприведенных ответов), предполагая, что проблема заключается в том, что к моменту завершения обратного вызова 'u' получает свое значение с самого последнего итерации цикла. – meetamit

+0

Мои навыки работы с Javascript ограничены, поэтому, если вы покажете мне, как это сделать, я бы очень признателен. @meetamit да, это то, что происходит –

ответ

1

Что-то вроде этого (скрипка: http://jsfiddle.net/EYAYT/2/)?

var urls = ["asd", "asdasd", "Asdasfa"]; 
var currentUrlIndex = 0; 
var getUrl = function(){ 
    if (currentUrlIndex >= urls.length){ 
     return null; 
    } else { 
     return "interest_points/" + urls[currentUrlIndex++] + ".csv"; 
    } 
} 

var execd3Text = function(){ 
    var url = getUrl(); 
    if (url){ 
     d3.text(url, function(text) {            

        //some code;; 
        execd3Text(); 
       }); 
    } 
} 

execd3Text(); 
+0

, вы можете исправить индексирование. Это начнется с 1 –

+0

Нет, это работает, проверьте скрипку. currentUrlIndex ++ сначала возвращает, а затем увеличивает. – pax162

+0

не уверен, потому что мне пришлось изменить его, чтобы работать, начиная с первого индекса ... Спасибо за ответ, хотя! –

0

Если я понял правильно:

function doSomething(array) { 
    var u = array.shift(); 
    console.log(u); 

    var url = "interest_points/" + urls[u] + ".csv"; 
    var data_gpBy_month = {}; 
    var sortable_month = [] 

    d3.text(url, function(text) { 
    // some code... 
    var data = d3.csv.parseRows(text).map(function(row) { 
    //some code...   
    }); 

    //some code 

    if (array.length > 0) 
     doSomething(array); 
});   


doSomething(Object.keys(urls)); 
1

Петля должна просто стать этим:

for(var u in urls) { loadParseAndRender(u); } 

Все существующая логика затем переходит в loadParseAndRender, но в этот момент u никогда не получит переопределены. I.e, в фантастических терминах, он захватывается в закрытии.

function loadParseAndRender(u) { 
    // the rest of your code 
} 

Что David W предложил то же самое, как abive, но без создания имени функции для этого, вы могли бы сделать это:

for(var _u in urls) { 
    (function(u) { // this is an anonymous function 
    // the rest of you code 
    })(_u) // this function gets called as soon as it's declared 
} 
+0

Привет, милый, это хорошо, но оп упомянул, что ему нужен цикл, чтобы перейти к следующей итерации после завершения предыдущей итерации. Если я правильно понимаю, то выполнение этого так, с вызовом функции, не гарантирует порядок выполнения обратного вызова. Это будет зависеть от того, как быстро возвращается ajax. – pax162

+0

@ pax162 Это правда ... заказ не гарантируется. – meetamit

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