我正在尝试编译我从多个API调用中获取的数据列表,但是在构建数组并陷入无限递归方面存在问题。
调用递归函数的函数:
jsonToCsv () {
this.exportCSV().then(data => {
console.log('From jsonToCSV', data)
})
}
递归功能
exportCSV (uidList = this.checkboxList.slice(), offset = 0) {
// Get query, build request
let request = {
id: 'export',
query: this.currentQuery.query,
sort: this.currentQuery.sort,
limit: 100, // how much data is returned
offset: offset // pagination value
}
return new Promise((resolve, reject) => {
// using Vuex to fetch data, returns an array of objects.
this.$store.dispatch('show/fetchQuery', request).then(data => {
let headerList = this.shownHeaders // an array of column id's & thier 'nice names'
let output = []
let row, uid, header
// match the id's to the Data from the API call
for (uid = 0; uid < uidList.length; uid++) {
for (row = 0; row < data.length; row++) {
if (data[row].uid === uidList[uid]) {
let rowData = {}
uidList.splice(uid, 1) // found this id so remove from list
// take data from query call that we want, make objects, push them to array
for (header = 0; header < headerList.length; header++) {
let niceName = headerList[header].niceName
let id = headerList[header].id
rowData[niceName] = data[row][id]
}
output.push(rowData)
}
}
}
// Basecase
if (uidList.length === 0) {
resolve(output)
return
}
offset += 100 // get next 100 results from query
// run next recursive call
this.exportCSV(uidList, offset).then(newData => {
output.push(newData)
resolve(newData)
})
})
})
我相信我正确地处理了basecase,但是,如果必须多次调用查询,意味着2级递归,则只打印最新的递归调用返回值。数组输出被覆盖..如果不满足basecase,如何处理数据解析?
答案 0 :(得分:0)
var exportCSV = (uidList = this.checkboxList.slice(1), offset = 0) => {
return new Promise(function(resolveFinal){
var rec = (uidListTemp = uidList, offsetTemp = offset, output = [])=>{
let request = {
id: 'export',
query: this.currentQuery.query,
sort: this.currentQuery.sort,
limit: 100, // how much data is returned
offset: offset // pagination value
}
return new Promise((resolve, reject) => {
// using Vuex to fetch data, returns an array of objects.
this.$store.dispatch('show/fetchQuery', request).then(data => {
let headerList = this.shownHeaders // an array of column id's & thier 'nice names'
let row, uid, header
// match the id's to the Data from the API call
for (uid = 0; uid < uidList.length; uid++) {
for (row = 0; row < data.length; row++) {
if (data[row].uid === uidList[uid]) {
let rowData = {}
uidList.splice(uid, 1) // found this id so remove from list
// take data from query call that we want, make objects, push them to array
for (header = 0; header < headerList.length; header++) {
let niceName = headerList[header].niceName
let id = headerList[header].id
rowData[niceName] = data[row][id]
}
output.push(rowData)
}
}
}
resolve(output);
}).then(output=>{
//base case
if (uidList.length === 0) {
resolveFinal(output);
return output;
} else {
offset += 100 // get next 100 results from query
// run next recursive call
rec(uidList, offset, output)
}
});
});
}
rec();
})
}
答案 1 :(得分:0)
您应该将较新的结果与您已有的结果连接起来。因此,在最后一行中,您无法使用newData解析,而是使用output.concat(newData)
。另外,push
在这里是错误的......您需要concat
。
应该提到你正在应用promise构造函数antipattern,即你创建了一个你可以使用的promise。不需要new Promise
。
以下是它的外观:
exportCSV (uidList = this.checkboxList.slice(), offset = 0) {
// Get query, build request
let request = {
id: 'export',
query: this.currentQuery.query,
sort: this.currentQuery.sort,
limit: 100, // how much data is returned
offset: offset // pagination value
}
// using Vuex to fetch data, returns an array of objects.
// (don't create a new promise when can return an existing one)
return this.$store.dispatch('show/fetchQuery', request).then(data => {
// Basecase
if (uidList.length === 0) {
return [];
}
let headerList = this.shownHeaders // an array of column id's & thier 'nice names'
let output = []
let row, uid, header
// match the id's to the Data from the API call
for (uid = 0; uid < uidList.length; uid++) {
for (row = 0; row < data.length; row++) {
if (data[row].uid === uidList[uid]) {
let rowData = {}
uidList.splice(uid, 1) // found this id so remove from list
// take data from query call that we want, make objects, push them to array
for (header = 0; header < headerList.length; header++) {
let niceName = headerList[header].niceName
let id = headerList[header].id
rowData[niceName] = data[row][id]
}
output.push(rowData);
// Probably you can now break out of this loop as you
// will not expect a second match
break;
}
}
}
// run next recursive call, return the promise
return this.exportCSV(uidList, offset + 100).then(newData => {
// append to previous results
return output.concat(newData);
})
})
}