2013-11-11 3 views
5

Есть ли способ сделать d3.csv() синхронным вместо асинхронного?d3: сделать функцию d3.csv синхронной

Мой код становится беспорядочным с обратными вызовами, так как я загружаю несколько файлов csv в соответствии с различными триггерами на странице.

ответ

8

d3.csv является асинхронным по дизайну, чтобы предотвратить замораживание страниц, поэтому его нельзя изменить без изменения самой библиотеки d3.

Однако вы можете предварительно загрузить все свои файлы через d3.text() и вызвать d3.csv.parse или d3.csv.parseRows, которые будут синхронными, если загружен текстовый файл.

Для примера см. Ответ Майка Бостока в этом сообщении this post.

+1

все функции вы упомянули асинхронно. Они делают запросы AJAX, поэтому вы не можете сделать их синхронными. Если вы хотите синхронную загрузку данных, вам необходимо внедрить данные на странице. –

1

Если это невозможно с d3 (как упоминалось в THK), это возможно с помощью jquery.ajax(), где есть асинхронное поле, которое может быть установлено на false. См. Пример ниже:

function getdatafromfile(filename) { 
// Read annotation file. Example : %timeinstant \t %value \n 
// Return an array of string 
var arraydata; 
$.ajax({ 
     type: "GET", 
     url: filename, 
     dataType: "text", 
     async: false, 
     success: function(csv) {arraydata = $.csv.toArrays(csv,{separator:'\t'}); } 
     }); 
return arraydata; 
} 
+0

Точка с запятой не требуется на 'var' и' return'? Этот стандарт js позволяет? – javadba

+0

и, кстати, это похоже на хорошее решение. Есть ли что-то подобное для более общей обработки (т. Е. Не обязательно выборки?) – javadba

+0

@javadba. Я отредактировал ответ и добавил точки с запятой. Спасибо за комментарии – PatriceG

1

Вы можете решить 'call back hell', объединив d3.js с отсрочкой/обещанием.

Пример с Jquery.deferred:

var getCsv = function (csvUrl) { 
    var defer = $.Deferred(); 
    d3.csv(csvUrl, function (error, rows) { 
     if (error) { 
      defer.reject(error); 
     } 
     defer.resolve(rows); 
    }); 
    return defer.promise(); 
}; 

$.when(
    getCsv("data/test1.csv"), // please pass csv url as you like 
    getCsv("data/test2.csv") // please pass csv url as you like 
).done(function (res1, res2) { 
    console.log(res1); // test1.csv parsed by d3.js 
    console.log(res2); // test2.csv parsed by d3.js 
}).fail(function (err) { 
    console.log(err); 
}); 
Смежные вопросы