游戏随机模具生成异步代码卡顿问题及优化方案咨询
Hey there, let's break down why this code might be causing performance hits and how to fix it quickly. The biggest issue here is that you're making dozens of sequential async calls to RandomChance, each one waiting for the previous to finish—plus there's a ton of repetitive code adding unnecessary overhead. Here's how to optimize this drastically:
核心问题分析
- 串行异步调用累积延迟: 每次
await this.bot.functions.RandomChance()is an async operation (maybe database queries, external API calls, or heavy computations). 20+ sequential calls multiply the latency by 20, which is the main cause of your lag. - Redundant code bloat: Every branch repeats
Embed.addField()andsetDescription(), which is not only unnecessary but also risks inconsistencies. - Inefficient probability checking: Checking each condition one by one means in the worst case (like rolling for wood), you run through all 25+ branches—wasting resources for no reason.
优化后的代码实现
We can centralize the probability-mold mapping, then use a single random calculation to get the result, eliminating most async calls entirely:
async RandomMold(initialMold: string, Embed: MessageEmbed, message: Message) { // 1. Centralize weight-mold mappings for easy maintenance const moldWeightMap = [ { weight: 8803062364500000000000, mold: Molds.soulstone }, { weight: 1303062364500000000000, mold: Molds.mythril }, { weight: 203062364500000000000, mold: Molds.aquamarine }, { weight: 30802364500000000000, mold: Molds.ammolite }, { weight: 4667364500000000000, mold: Molds.quartz }, { weight: 707364500000000000, mold: Molds.volcanic }, { weight: 1072364500000000000, mold: Molds.azure }, { weight: 162364500000000000, mold: Molds.painite }, { weight: 24596450000000000, mold: Molds.fossil }, { weight: 3724645000000000, mold: Molds.topaz }, { weight: 5646450000000, mold: Molds.moonstone }, { weight: 855500000000, mold: Molds.bloodstone }, { weight: 1296450000000, mold: Molds.crystal }, { weight: 196450000000, mold: Molds.sulfur }, { weight: 297500000000, mold: Molds.uranium }, { weight: 45080000000, mold: Molds.opal }, { weight: 6450000000, mold: Molds.diamond }, { weight: 801456019, mold: Molds.amethyst }, { weight: 102891786, mold: Molds.ruby }, { weight: 13673213, mold: Molds.emerald }, { weight: 1882668, mold: Molds.sapphire }, { weight: 6145, mold: Molds.gold }, { weight: 985.87, mold: Molds.silver }, { weight: 164.81, mold: Molds.copper }, { weight: 28.75, mold: Molds.bronze }, { weight: 28.75, mold: Molds.stone }, { weight: 1, mold: Molds.wood } // Fallback weight to ensure coverage ]; // 2. Calculate total weight to set the random range const totalWeight = moldWeightMap.reduce((sum, item) => sum + item.weight, 0); // 3. Single async call to get a random value (adjust if your RandomChance logic differs) // If your original RandomChance just checks "random <= weight", replace this with a call that returns a value between 0 and totalWeight const randomValue = await this.bot.functions.getRandomValue(totalWeight, message); // 4. Find the matching mold by checking weight ranges let currentSum = 0; let selectedMold = initialMold; for (const item of moldWeightMap) { currentSum += item.weight; if (randomValue <= currentSum) { selectedMold = item.mold; break; } } // 5. Update Embed in one place to avoid repetition Embed.addField("Mold", selectedMold, true); const nonCommonMolds = [Molds.copper, Molds.bronze, Molds.stone, Molds.wood]; if (!nonCommonMolds.includes(selectedMold)) { Embed.setDescription(`You got a rare item! Mold: ${selectedMold}`); } return selectedMold; }
关键优化点说明
- Cut async calls from 25+ to 1: This eliminates the cumulative delay of waiting for multiple async operations to finish one after another—this is the biggest win for performance.
- Centralized configuration: All weight and mold pairs live in one array, so updating probabilities or adding new molds only requires changing this list, making the code way easier to maintain.
- Unified logic: All Embed updates happen in one spot, removing redundant code and reducing the chance of bugs.
- Faster probability matching: Instead of checking each condition sequentially, we calculate the weight range once and find the match in a single loop—much more efficient.
额外建议
If your RandomChance function doesn't actually need to be async (e.g., it's just generating a local random number), convert it to a sync function to squeeze out even more performance. And since your rarity/quality modules use the same logic, you can reuse this exact pattern for them too—refactoring all of them will give your game a massive performance boost.
内容的提问来源于stack exchange,提问作者FSCYT

