javascript - 如何获取 CSV 格式的数据输出?
问题描述
这是我的代码:
var idFiltered = "";
var artists = [];
var country = "";
var released = "";
var genres = [];
var styles = [];
var tracklist = [];
var rows = [
[idFiltered, artists, country, released, genres, styles, tracklist],
];
var csvContent = [];
function id(file) {
return new Promise((resolve, reject) => {
reader = new FileReader();
reader.onload = function(e) {
parsedLines = e.target.result.split(/\r|\n|\r\n/);
resolve(parsedLines);
};
reader.readAsText(file);
});
}
document.getElementById('fileInput').addEventListener('change', function(e) {
var file = e.target.files[0];
if (file != undefined) {
id(file).then(id => {
console.log(id)
console.log(parsedLines)
console.log(typeof id);
var idInt = id.map(Number);
idFiltered = id.filter(function(v){return v!==''});
console.log(idFiltered)
idFiltered.forEach(idFiltered => {
getRelease(idFiltered);
});
download(csvContent);
});
}
});
function getRelease(idFiltered) {
return fetch(`https://api.*******.com/releases/${idFiltered}`, {
'User-Agent': 'Dispodger/0.1',
})
.then(response => response.json())
.then(data => {
if (data.message === 'Release not found.') {
return { error: `Release with ID ${idFiltered} does not exist` };
} else {
const id = data.id;
artists = data.artists ? data.artists.map(artist => artist.name) : [];
country = data.country || 'Unknown';
released = data.released_formatted || 'Unknown';
genres = data.genres || [];
styles = data.styles || [];
tracklist = data.tracklist ? data.tracklist.map(track => track.title) : [];
console.log(idFiltered);
console.log(artists, country, released, genres, styles, tracklist)
rows = [
[idFiltered, artists, country, released, genres, styles, tracklist],
];
console.log(rows);
}
});
}
function download() {
const ROW_NAMES = ["Release ID", "artists", "country", "released", "genres", "styles", "tracklist"];
csvContent = "data:text/csv;charset=utf-8,"
+ ROW_NAMES + "\n" + rows.map(e => e.join(",")).join("\n");
console.log(csvContent);
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for FF
link.click();
}
当我在第 72 行 console.logrows
时,数据显然在那里,并且似乎我成功地抓取了数据但只是将其丢弃;它显然永远不会进入download
函数。我最初将下载功能作为 的一部分GetRelease()
,但效果不佳,我每行得到一个文件,尽管有我想要的数据。现在我只得到一个文件,但数据不存在,只包含标题。请问有什么帮助吗?TIA。
编辑:我开始怀疑我是否可能返回错误的东西getRelease
?也许不是return fetch
我需要做的return rows
?
解决方案
getRelease
是异步的。它返回一个 Promise,而不是一个值。你不能简单地做idFiltered.forEach( getRelease )
。
getRelease
解决方案:用async/await
语法重写
async function getRelease(idFiltered) { // Returns a Promise
const response = await fetch(...);
const data = await response.json();
if (data.message === 'Release not found.') {
return { error: `Release with ID ${idFiltered} does not exist` };
} else {
// ....
console.log(rows);
return rows;
}
}
现在你可以这样做:
for( let id of idFiltered){
await getRelease(id);
}
这将使每个fetch
呼叫按顺序进行,一个接一个。或者,您可以使它们全部与Promise.all
:
await Promise.all( idFiltered.map(getRelease) );
然后就可以了download(csvContent);
。
document.getElementById('fileInput')
.addEventListener('change', async function (e) { // add "async"
const file = e.target.files[0];
if (!file) return;
const id2 = await id(file);
console.log(id2)
console.log(parsedLines)
console.log(typeof id2);
const idFiltered = id2.filter(v => v !== '');
console.log(idFiltered)
await Promise.all(idFiltered.map(id => getRelease(id) ));
download(csvContent);
});
推荐阅读
- css - 以响应方式将中间内容移动到桌面侧边栏
- html - 如何在使用 Storm-crawler 抓取网页时排除带有 id/class、页眉和页脚部分的 HTMl 的特定 DIV?
- prometheus - Prometheus java 客户端和 Prometheus 服务器兼容性
- airflow - 气流任务设置为未在此池中排队的池
- excel - 从 Power Query 中的列中删除标点符号
- javascript - 寻找带有输入编号的 React Multiselect 组件
- react-native - 尝试从文件中解析模块`fs`
- swift - CoreData:此类对于关键文件夹位置不符合关键值编码
- mysql - Sql 查询从另一个表中选择与表的单行上的值相关的多个项目
- javascript - React 无法设置 React Hooks 的状态