为什么网页运行一天后百分比出现混乱?

问题描述 投票:0回答:1

在此代码中,月份应该重置“每周的每个月”、“每周和每天”和“每天”。

根据代码的编写方式,当单日运行时,每天的百分比应该是唯一的,而每周和每月的百分比应该保持一致并与每日值相匹配。然而,运行代码一天后,每周和每天的百分比是相同的,但每月的百分比不同。我不确定为什么会发生这种情况,因为每周和每月的百分比应该保持不变,直到一周过去。

此外,我想知道这是否会受到在本地计算机上运行 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 小时后的月值与周和日不同。

我添加了调试语句并多次运行代码以尝试找出答案。

math next.js server
1个回答
0
投票

我在这里看到几点

首先:你把事情过于简单化了,因为一天(一周)并不总是有 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(); }
这样您在进行计算之前就可以确定所有历史价格都处于正确的值。并且它们仅在您期望的时间间隔内更新。即,您没有多个相互依赖且依赖于特定执行顺序的回调。

© www.soinside.com 2019 - 2024. All rights reserved.