
[英]Need help -> Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
[英]Uncaught (in promise) TypeError: Cannot read property 'length' of undefined at promiseKey.then
我试图从promise返回一个推送数据数组,然后多次循环以填充所有数据。 例如,我得到了一个品牌列表和一个接受品牌参数并返回推送数据数组的函数。
var datasetarr = [];
brandlist = ['Bh', 'Ruffles'];
let promiseKey = new Promise((resolve, reject) => {
for(var i = 0; i < brandlist.length; i++){
datasetarr = populateData(brandlist[i], datasetarr);
}
resolve(datasetarr);
});
promiseKey.then((arr) => {
console.log('complete promise');
for(var i = 0; i < arr.length; i++){
console.log(arr[i].date + ' ' + arr[i].total);
}
});
错误消息是
Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
at promiseKey.then
由于设法打印出详细信息,因此数据获取没有问题。 这意味着承诺没有正确解决。 这是从promise返回数组的正确方法吗? 我不确定哪一部分错了。
首先,您的populateData需要返回一个Promise-在这种情况下,它将是在data.forEach中创建的已解决的promise数组。
var brandlist = ['Bh', 'Ruffles'];
let promiseKey = Promise.all(brandlist.map(brand => populateData(brand)))
.then(results => [].concat(...results)); // flatten the array of arrays
promiseKey.then((arr) => {
console.log('complete promise');
for(var i = 0; i < arr.length; i++){
console.log(arr[i].date + ' ' + arr[i].total);
}
});
function populateData(brand, datasetarr) {
console.log('go in');
var query;// = // query by brand parameter
return query.once('value').then(data => {
var promises = [];
data.forEach(snapshot => {
// get each receipt item details
// get receipt details by receipt ID
var query;// = // query receipts
promises.push(query.once('value').then(data => {
// removed code
// managed to print out here so data fetching is not a problem
console.log(brand + ' ' + date + ' ' + itemTotal);
return {date: date, total: itemTotal};
}));
});
return Promise.all(promises);
});
}
或者,使用一周前我在此答案中给您的snapshotToArray
函数
const snapshotToArray = snapshot => {
const ret = [];
snapshot.forEach(childSnapshot => {
ret.push(childSnapshot);
});
return ret;
};
function populateData(brand, datasetarr) {
console.log('go in');
var query;// = // query by brand parameter
return query.once('value').then(data => Promise.all(snapshotToArray(data).map(snapshot => {
// get each receipt item details
// get receipt details by receipt ID
var query;// = // query receipts
return query.once('value').then(data => {
// removed code
// managed to print out here so data fetching is not a problem
console.log(brand + ' ' + date + ' ' + itemTotal);
return {date: date, total: itemTotal};
});
})));
}
虽然可以使用从任何地方push
送到的全局数据集datasetarray
变量,但我还是建议不datasetarray
。 而是编写一个getData
方法,该方法返回一个数组(对数组的承诺),并在多次调用后(每个品牌一次)将它们连接在一起。
const brandlist = ['Bh', 'Ruffles'];
const promiseKey = Promise.all(brandlist.map(getData)).then(arrays => [].concat(...arrays));
promiseKey.then(arr => {
console.log('complete promise');
for (const item of arr)
console.log(item.date + ' ' + item.total);
});
function getData(brand) { // no array parameter!
console.log('go in');
const query = …; // query by brand parameter
return query.once('value').then(data => {
const promises = toArray(data).map(snapshot => {
const query = …; // get receipt item details by receipt ID
return query.once('value').then(data => {
…
return {date: date, total: itemTotal}; // don't push, just return the result
});
return Promise.all(promises); // resolves with an array of results
}); // resolves with that same result array
}
function toArray(forEachable) {
const arr = [];
forEachable.forEach(x => { arr.push(x); });
return arr;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.