Reputation: 63728
Is there any way to make d3.csv() be synchronous instead of asynchronous?
My code is getting to be a mess with callbacks since I load multiple csv files according to different triggers on the page.
Upvotes: 9
Views: 10325
Reputation: 4063
If it is not possible with d3 (as mentioned by THK), it is possible with jquery.ajax(), where there is an async field that can be set to false. See the example below:
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;
}
Upvotes: 1
Reputation: 2897
You can solve 'call back hell' by combining d3.js with deferred/promise.
Example with 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);
});
Upvotes: 1
Reputation: 701
d3.csv is asynchronous by design to prevent pages from freezing up, so that can't be changed without changing the d3 library itself.
However, you could pre-load all your files via d3.text() and call d3.csv.parse or d3.csv.parseRows, which will be synchronous given that the text file has been loaded.
For an example, see Mike Bostock's answer in this post this post.
Upvotes: 12