Discord.js:如何确保Embed构建完成后再发送(物品检测场景)
I have a module called Potential Cyno that detects if a user lost a ship carrying a specific item (item ID 21096), but the detection results are unstable. It seems like the Embed is being sent before the item check completes and the corresponding field is added, so sometimes the field appears and sometimes it doesn't.
Here's my current code:
let cynoLosses = []; snekfetch.get(losses).then(l => { for (var c = 0; c < l.body.length; c++) { var item = l.body[c].victim.items; for (var items = 0; items < item.length; items++) { if (item[items].item_type_id === 21096 && cynoLosses.length < 1) { cynoLosses.push(l.body[c].killmail_id); console.log(l.body[c].killmail_id); embed.addField("POTENTIAL CYNO", "https://zkillboard.com/kill/" + cynoLosses[0] + "/"); } } } }).catch(err => { console.log(err); });
How can I ensure the Embed is only sent after the detection is fully completed?
The core issue here is asynchronous execution order. Your snekfetch.get() request runs asynchronously—meaning JavaScript continues executing other code (like sending the Embed) while waiting for the API response. If your Embed send logic lives outside the .then() callback, it will fire before the item check finishes, leading to the inconsistent behavior you're seeing.
Here are two solid fixes, plus some optimizations to clean up your code:
1. Move Embed Sending Inside the .then() Callback
Ensure all data processing and field addition completes before you send the Embed by placing the send logic directly inside the promise's .then() block:
// Initialize your Embed first (adjust based on your library, e.g., discord.js) const embed = new MessageEmbed() .setTitle("Losses Summary") .setColor("#e74c3c"); snekfetch.get(losses) .then(l => { let cynoLosses = []; // Loop through losses with cleaner syntax (optional but easier to read) for (const loss of l.body) { for (const item of loss.victim.items) { if (item.item_type_id === 21096 && cynoLosses.length === 0) { cynoLosses.push(loss.killmail_id); console.log(loss.killmail_id); embed.addField("POTENTIAL CYNO", `https://zkillboard.com/kill/${cynoLosses[0]}/`); // Break inner loop once we find the first match break; } } // Break outer loop if we already found a cyno loss if (cynoLosses.length > 0) break; } // Send the Embed ONLY after processing all data message.channel.send({ embeds: [embed] }); // Adjust to your bot's send syntax }) .catch(err => { console.error("Failed to fetch losses:", err); // Add error feedback to the Embed and send it embed.addField("Error", "Could not retrieve loss data."); message.channel.send({ embeds: [embed] }); });
2. Use async/await for Cleaner, Linear Logic
If you prefer more readable code (avoiding "callback hell"), switch to async/await syntax. This makes asynchronous code behave more like synchronous code:
// Wrap everything in an async function async function checkForCynoLosses() { const embed = new MessageEmbed() .setTitle("Losses Summary") .setColor("#e74c3c"); try { // Wait for the API response to complete const response = await snekfetch.get(losses); let cynoLosses = []; for (const loss of response.body) { for (const item of loss.victim.items) { if (item.item_type_id === 21096 && cynoLosses.length === 0) { cynoLosses.push(loss.killmail_id); console.log(loss.killmail_id); embed.addField("POTENTIAL CYNO", `https://zkillboard.com/kill/${cynoLosses[0]}/`); break; } } if (cynoLosses.length > 0) break; } // Send the Embed after all processing await message.channel.send({ embeds: [embed] }); } catch (err) { console.error("Failed to fetch losses:", err); embed.addField("Error", "Could not retrieve loss data."); await message.channel.send({ embeds: [embed] }); } } // Call the async function checkForCynoLosses();
Key Optimizations
- Early termination: Once we find the first matching cyno loss, we break out of both loops—no need to waste resources checking the rest of the data.
- Error handling: Added clear error feedback in the Embed so users know if something goes wrong.
- Readability: Switched from
forloops with counters tofor...ofloops, which are easier to follow.
内容的提问来源于stack exchange,提问作者Anure

