在此代码中,月份应该重置“每周的每个月”、“每周和每天”和“每天”。
根据代码的编写方式,当单日运行时,每天的百分比应该是唯一的,而每周和每月的百分比应该保持一致并与每日值相匹配。然而,运行代码一天后,每周和每天的百分比是相同的,但每月的百分比不同。我不确定为什么会发生这种情况,因为每周和每月的百分比应该保持不变,直到一周过去。
此外,我想知道这是否会受到在本地计算机上运行 Next.js 应用程序并全天间歇性打开和关闭计算机的影响。这会干扰值的存储吗?
这是代码:
import { NextResponse } from 'next/server';
let holdersCount: number | null = null;
let priceData: { priceUsd: number, marketCap: string ,liquidity: string} = { priceUsd: 0, marketCap: '' ,liquidity: ''};
let priceHistory = {
month: 0, // Use numbers
day: 0,
week: 0,
};
let pctChange = {
month: '0.00', // Keep as strings for output
day: '0.00',
week: '0.00',
};
let isInitialFetch = true;
{/* deleted the fetch holder function for simplicity*/}
const fetchPriceData = async () => {
try {
const response = await fetch('https://api.dexscreener.com/latest/dex/tokens/0x9a26F5433671751C3276a065f57e5a02D2817973');
const data = await response.json();
priceData = {
priceUsd: parseFloat(data.pairs[0].priceUsd) || 0, // Ensure it's always a valid number
marketCap: data.pairs[0].marketCap,
liquidity: data.pairs[0].liquidity.usd
};
if (isInitialFetch) {
// Only set the initial prices after the first successful fetch
priceHistory.month = priceData.priceUsd;
priceHistory.day = priceData.priceUsd;
priceHistory.week = priceData.priceUsd;
isInitialFetch = false; // Disable the flag after setting the initial prices
console.log('inital state done')
}
console.log("Old price:", priceHistory.month);
console.log("Current price:", priceData.priceUsd);
// Calculate the percentage change for each timeframe
const calculatePercentChange = (oldPrice: number, newPrice: number): string => {
if (oldPrice === 0 || isNaN(oldPrice) || isNaN(newPrice)) {
return '0'; // Avoid invalid calculations or division by 0
}
const percentChange = ((newPrice - oldPrice) / oldPrice) * 100;
return percentChange > 0 ? `+${percentChange.toFixed(2)}` : percentChange.toFixed(2);
};
// Only calculate percentage change if the old prices have been set and are valid
if (priceHistory.month > 0) {
pctChange.month = calculatePercentChange(priceHistory.month, priceData.priceUsd);
}
if (priceHistory.day > 0) {
pctChange.day = calculatePercentChange(priceHistory.day, priceData.priceUsd);
}
if (priceHistory.week > 0) {
pctChange.week = calculatePercentChange(priceHistory.week, priceData.priceUsd);
}
console.log("Price data updated:", priceData);
console.log("Percentage change:", pctChange);
} catch (error) {
console.error('Error fetching price data:', error);
}
};
// Fetch holders data every 8 hrs
setInterval(fetchHoldersData, 8 * 60 * 60 * 1000);
// Fetch price data every 8 hrs
setInterval(fetchPriceData, 8 * 60 * 60 * 1000);
// Reset the price history every hour, day, and week
setInterval(() => {
priceHistory.month = priceData.priceUsd;
},31 * 24 * 60 * 60 * 1000); // Every month
setInterval(() => {
priceHistory.day = priceData.priceUsd;
}, 24 * 60 * 60 * 1000); // Every day
setInterval(() => {
priceHistory.week = priceData.priceUsd;
}, 7 * 24 * 60 * 60 * 1000); // Every week
// Initial fetch
fetchHoldersData();
fetchPriceData();
export async function GET() {
return NextResponse.json({
holders: holdersCount,
price: priceData.priceUsd.toFixed(2),
marketCap: priceData.marketCap,
liquidity: priceData.liquidity,
percentChanges: pctChange,
});
}
日值应与周和月值不同,而不是 24 小时后的月值与周和日不同。
我添加了调试语句并多次运行代码以尝试找出答案。
我在这里看到几点
首先:你把事情过于简单化了,因为一天(一周)并不总是有 24 (168) 小时(即 DST 切换发生时),一个月也不总是有 31 天。但这只是一个旁注,而且肯定不是问题的原因。也许这甚至适合您的用例。这是你的决定。
第二:这种情况是在最初 24 小时之后发生还是在后端运行较长时间之后发生?因为,实际上我看不到任何方式(在您此处显示的代码中)在前 31 天中“每月”间隔的回调在“每日”或“每周”之前执行。这是唯一改变
priceHistory.month
的地方(除了最初的请求)吗?
第三:在长期运行情况下(即超过一个月),一个问题可能是,所有间隔都是彼此的精确倍数,即 31 天后,所有回调都计划在同一时间执行,并且它 最终可能会发生,它们没有按照您期望的顺序执行,即它可以更新 history.month
,然后获取新价格并计算新百分比,然后仅更新
history.week
和
history.day
。为了克服这些问题,我建议使用不同的数据结构和策略来获取和更新您的值。
与您的数据一起存储时间戳,其中每个值上次更新的位置
let history = {
day: 0,
dayupdated: 0,
week: 0,
weekupdated: 0,
month: 0,
monthupdated: 0
};
let priceData = {...};
let priceUpdated = 0;
...
然后使用单个(可能更频繁)间隔并在其回调中检查您实际需要做什么
setInterval(doWork, 3600000);
doWork(); //do the inital call
async function fetchPriceData() {
const response = await fetch('https://api.dexscreener.com/latest/dex/tokens/0x9a26F5433671751C3276a065f57e5a02D2817973');
const data = await response.json();
priceData = {
priceUsd: parseFloat(data.pairs[0].priceUsd) || 0, // Ensure it's always a valid number
marketCap: data.pairs[0].marketCap,
liquidity: data.pairs[0].liquidity.usd
};
}
function calcChanges() {
if (priceHistory.month > 0) {
pctChange.month = calculatePercentChange(priceHistory.month, priceData.priceUsd);
}
if (priceHistory.day > 0) {
pctChange.day = calculatePercentChange(priceHistory.day, priceData.priceUsd);
}
if (priceHistory.week > 0) {
pctChange.week = calculatePercentChange(priceHistory.week, priceData.priceUsd);
}
}
async function doWork() {
let now = Date.now();
//do this every 8 hours;
if (now - priceUpdated >= 8 * 3600000) {
await fetchPriceData();
priceUpdated = now;
}
//do this every 24 hours
//or find a condition, that works better with DST switches
if (now - history.dayUpdated >= 24*3600000) {
history.day = priceData.priceUsd;
history.dayUpdated = now;
}
//do this every 7 days
//or find a condition, that works better with DST switches
if (now - history.weekUpdated >= 24*7*3600000) {
history.week= priceData.priceUsd;
history.weekUpdated = now;
}
//do this every 31 days
//or find a condintion, that works with different numbers of days in month
if (now - history.monthUpdated >= 24*7*31*3600000) {
history.month = priceData.priceUsd;
history.monthUpdate = now;
}
calcChanges();
}
这样您在进行计算之前就可以确定所有历史价格都处于正确的值。并且它们仅在您期望的时间间隔内更新。即,您没有多个相互依赖且依赖于特定执行顺序的回调。