问题
I am trying to load data from a csv file and store the data in a dictionary variable named store as key routes. The first lines of the csv file look like this:
ID,AirlineID,AirlineName,AirlineCountry,SourceAirportID,SourceAirportCode,SourceAirport,SourceCity,SourceCountry,SourceLatitude,SourceLongitude,DestAirportID,DestCode,DestAirport,DestCity,DestCountry,DestLatitude,DestLongitude
1,24,American Airlines,United States,4355,ABE,Lehigh Valley International Airport,Allentown,United States,40.65209961,-75.44080353,3876,CLT,Charlotte Douglas International Airport,Charlotte,United States,35.2140007,-80.94309998
2,24,American Airlines,United States,4355,ABE,Lehigh Valley International Airport,Allentown,United States,40.65209961,-75.44080353,3752,PHL,Philadelphia International Airport,Philadelphia,United States,39.87189865,-75.2410965
3,24,American Airlines,United States,3718,ABI,Abilene Regional Airport,Abilene,United States,32.41130066,-99.68190002,3670,DFW,Dallas Fort Worth International Airport,Dallas-Fort Worth,United States,32.896801,-97.03800201
Here is how I am trying load the data and store the results onto store.routes. I only get an empty "{}" dictionary in the console.
let store = {};
function loadData() {
let promise = d3.csv("routes.csv")
return promise.then(routes => {
store.routes = routes;
return store;
})
}
loadData();
console.log(store.routes);
回答1:
What might be confusing here, is that the data loading is asynchronous, meaning that you have to wait until the promise is resolved before you can use the data.
You have a couple of options of going about this - a callback, a promise, or async/await. I've wrote a short script exemplifying their usage:
const store = {};
const doViz = (routes, dataRetrievalOrigin) => {
console.log(routes, dataRetrievalOrigin)
store.routes = routes
}
const loadDataWithCallback = (callback) => {
d3.csv("../data/routes.csv")
.then((routes) => {
callback(routes)
})
}
loadDataWithCallback((routes) => {
doViz(routes, 'Data loaded from loadDataWithCallback')
})
const loadDataWithPromise = () => {
return d3.csv("../data/routes.csv")
}
loadDataWithPromise().then((routes) => {
doViz(routes, 'Data loaded from loadDataWithPromise')
})
const loadDataWithAsync = async () => {
return d3.csv("../data/routes.csv")
}
;(async () => {
doViz(await loadDataWithAsync(), 'Data loaded from loadDataWithAsync')
})()
The common trait among the three examples are that they
- Initiate a data retrieval request via
d3.csv - Waits until the data retrieval is complete
- Calls the
doVizfunction with the retrieved data
Given that d3.csv returns a promise, I'm guessing that the structure of loadDataWithPromise might the most straightforward one to use.
--- Edit ---
Here is how to do it, closely mimicking your current approach. Notice that console.log(store.routes) is put into a function, that is called when the Promise resolves. This makes sure it is executed after the asynchronous data retrieval is complete.
const store = {};
const logData = () => {
console.log(store.routes)
}
const loadData = () => {
return d3.csv('../data/routes.csv')
.then((routes) => {
store.routes = routes
logData()
})
}
loadData()
Hope this helps!
来源:https://stackoverflow.com/questions/57204863/loading-csv-data-and-save-results-to-a-variable