1

Two main questions here:

  1. We want to load files in parallel

  2. Because these files are loaded in parallel, we don't know the exact order they are loaded. I want to parse a key from each file name, with the array of file content parsed by d3.csv as their corresponding values

That is said, the returned results by

   q.awaitAll(function(error, results) { console.log("all done!"); });

should be

results={
  "key1":array_read_from_myData_key1.csv,
  "key2":array_read_from_myData_key2.csv,
  ...
  "key30":array_read_from_myData_key30.csv
}

How to add each file name as a key to each array (results[i]) below?

var q = queue(), // create the queue
    dataSources = [ // the data sources
        'myData_key1.csv',
        'myData_key2.csv',
        'myData_key3.csv',
        ...,
        'myData_key30.csv'
    ];


// Go through each data source and add it to the queue:
dataSources.forEach(function (source) {
    q.defer(function (callback) {
        d3.csv(source, callback);
    });
});

// Wait for all requests to be completed:
q.awaitAll(function (error, results) {
    console.log(results);
})
Osiris
  • 1,007
  • 4
  • 17
  • 30

1 Answers1

1

You could expand your call back inside here:

dataSources.forEach(function (source, index) {
  q.defer(function (callback) {
    d3.csv(source, function(data){
       var fileData = {
           name: dataSources[index],
           data: data
       };
       callback(fileData);
   });
  });
});

Based on your comment you could try doing the following but not 100% sure that it will work :

 var finalData = {};

 dataSources.forEach(function (source, index) {
  q.defer(function (callback) {
    d3.csv(source, function(data){
       if (data) {
         //regex the key from file name
         var matcher = /^(myData)_([a-z][a-z][a-z][0-9])\.csv$/;
         var key = matcher.exec(dataSources[index])[1];
         //assign value to external object
         finalData[key] = data;
         //callback success
         callback(true);
       }
       else {
        //log error if required
        callback(false);
       }
   });
  });
});

// Wait for all requests to be completed:
q.awaitAll(function (error, results) {
   console.log(finalData);
})

Hope this solves your issue.

Alex_B
  • 838
  • 7
  • 13
  • Thanks @Alex_B. It is very close to what I want. Is it possible to return the results as a dict instead of an array of dict? i.e. how to obtain results={ "key1":array_read_from_myData_key1.csv, "key2":array_read_from_myData_key2.csv, ... "key30":array_read_from_myData_key30.csv } – Osiris Jul 14 '15 at 21:13
  • The regex needs to be improved based on actual file names. – Alex_B Jul 15 '15 at 02:54
  • This doesn't work. q.awaitAll executed after loading the first csv file, not wait after all csv files loaded. And the first csv array now loaded into "error" variable of q.awaitAll. The "results" is undefined. Any further input? – Osiris Jul 15 '15 at 03:12
  • Sorry but both versions don't work. I cann't edit the comment above, – Osiris Jul 15 '15 at 03:34
  • change callback(true); to callback(null,finalData) and see what the result of finalData is. – Alex_B Jul 15 '15 at 11:57
  • That's beautiful! Can we add a progress loading bar computed by the number of files loaded divided by the total number of files? The native "progress" of d3.csv is only for one file loading. http://stackoverflow.com/questions/22796065/trying-to-add-an-xhr-to-queue-js-to-show-progress – Osiris Jul 15 '15 at 19:26
  • To be perfectly honest with you, I am not sure on how to accomplish this. Check queue documentation to see if it provides some sort of function call that would fire when individual process finishes. – Alex_B Jul 15 '15 at 19:39