我写了一个函数来过滤数组中的时间间隔。
该功能似乎正常工作,并且打印跳过和接受是适当的,并且打印没有错误。
但是,它导致一个空数组。
getDate()
是一个返回日期的函数,因此可以使用getTime()
将其解析为某个时间。可行。
async function getInterval(climatedata,harvestdate,period) {
return new Promise(function(resolve, reject) {
getDate(harvestdate,-1*period).then((sval)=>{
let start = sval.getTime();
getDate(harvestdate,0).then(async(eval)=>{
let end = eval.getTime();
let filtered = await Promise.all(climatedata.filter((curVal,index,arr) => {
getDate(curVal[0]).then((tval)=>{
let td = tval.getTime();
//console.log(start,td,end);
if(td >= start && td <= end) {
console.log("accept"); //although this is printed for the expected subset, nothing is in the filtered array.
return true;
} else {
//console.log("skip");
return false;
}
}).catch((err)=>{console.log(err);});
}));
console.log("filtered",filtered); //here I would expect an array with some rows.
//console.log("bef",climatedata.length,"aft",filtered.length); //this is always bef 8000 aft 0
resolve(filtered);
});
});
});
}
我也尝试使用.then() on Promise.all
进行sligth变体,但无济于事。
我在做什么错? 谢谢, 詹斯
答案 0 :(得分:4)
因此,您的代码存在一些问题。
首先,您的实际问题。请注意,filter
返回一个新数组,其中包含通过测试功能的元素。为了通过测试函数,在该函数的迭代中返回的任何真值都将意味着数组中该索引处的项目应通过。因此,您有:
await Promise.all(climatedata.filter((curVal,index,arr) => {
getDate(curVal[0])...
};
您的第一个直接问题是您没有在过滤器的回调函数中返回任何内容,这意味着您在过滤器的每次迭代中都返回undefined
。 undefined == false
,因此该次迭代不会通过测试。由于没有一项测试通过,因此您最终要得到的是:
await Promise.all([undefined, undefined, ...])
实际上将解析为undefined
的数组。
现在我们已经解决了这个问题,让我们清理一下整个代码。首先,由于您正在使用async
,因此几乎永远不需要使用new Promise
。将函数标记为async
会隐式地将其返回的内容包装在promise中,这意味着您不需要这样做。
// NOTE: I've removed your console.log statements to make it simpler to read
async function getInterval(climatedata,harvestdate,period) {
return getDate(harvestdate,-1*period).then((sval)=>{
let start = sval.getTime();
getDate(harvestdate,0).then(async(eval)=>{
let end = eval.getTime();
let filtered = await Promise.all(climatedata.filter((curVal,index,arr) => {
return getDate(curVal[0]).then((tval)=>{ // NOTICE: I added `return` here to beging to fix your filter problem
let td = tval.getTime();
if(td >= start && td <= end) {
return true;
} else {
return false;
}
}).catch((err)=>{console.log(err);});
}));
return filtered;
});
});
}
好吧,接下来,由于您身处async
世界,因此您无需使用.then
或.catch
:
async function getInterval(climatedata, harvestdate, period) {
let sval;
try {
sval = await getDate(harvestdate, -1 * period);
} catch (error) {
console.log('getting `sval` failed, oh no!');
throw error;
}
let start = sval.getTime();
let eval;
try {
eval = await getDate(harvestdate, 0);
} catch (error) {
console.log('getting `eval` failed, oh no!');
throw error;
}
let end = eval.getTime();
let filtered = await Promise.all(climatedata.filter(async (curVal,index,arr) => {
let tval;
try {
tval = getDate(curVal[0]);
} catch (error) {
console.log('getting `tval` failed, oh no!');
throw error;
}
let td = tval.getTime();
if(td >= start && td <= end) {
return true;
} else {
return false;
}
}));
return filtered;
}
好多了。但是好吧,让我们再次探讨问题的实质:您希望过滤掉承诺清单。这意味着您不仅可以使用filter
,还需要使用filter
和map
:
async function getInterval(climatedata, harvestdate, period) {
let sval;
try {
sval = await getDate(harvestdate, -1 * period);
} catch (error) {
console.log('getting `sval` failed, oh no!');
throw error;
}
let start = sval.getTime();
let eval;
try {
eval = await getDate(harvestdate, 0);
} catch (error) {
console.log('getting `eval` failed, oh no!');
throw error;
}
let end = eval.getTime();
const filterTest = (curVal, index, arr)
const climatedataPromises = climatedata.map(curVal => getDate(curVal[0])); // Create a list of promises
const climatedata = await Promise.all(climatedataPromises); // Wait for them all to return
return climatedata.filter((tval, index) => { // Now run your filter
let td = tval.getTime();
if(td >= start && td <= end) {
return true;
} else {
return false;
}
});
}
享受:)
*我不保证我不会在某个地方缺少闭括号或括号:)