如何从异步操作获取变量并生成带随机ID的URL模板字符串?
Got it, let's walk through this step by step to get your random user profile link working smoothly. We'll cover async data fetching from MongoDB, picking a random ID with Lodash, generating the URL, and rendering it in your EJS template—plus explain how to handle async variables properly.
Step 1: Backend Logic (Express + MongoDB + Lodash)
First, we need to fetch all user IDs from MongoDB, pick a random one, and generate the URL. Since MongoDB queries are asynchronous, we'll use async/await (cleaner than raw Promises) to handle the flow.
Make sure you have the required dependencies installed:
npm install lodash mongoose express ejs
Here's the route handler code (assuming you're using Express and have a User model set up):
const express = require('express'); const _ = require('lodash'); const User = require('./models/User'); // Update this to your User model path const app = express(); // Set EJS as the view engine app.set('view engine', 'ejs'); // Route to render the index page with random profile URL app.get('/', async (req, res) => { try { // Fetch all unique user IDs from MongoDB (async operation) const userIds = await User.find({}).distinct("_id"); // Handle edge case: no users in the database if (userIds.length === 0) { return res.render('index', { profileUrl: null }); } // Pick a random ID from the array using Lodash's sample() const randomId = _.sample(userIds); // Generate the final URL string with the random ID const profileUrl = `http://localhost:9090/api/${randomId}`; // Pass the URL to your EJS template res.render('index', { profileUrl }); } catch (error) { console.error('Failed to fetch user IDs:', error); res.status(500).send('Oops, something went wrong on our end!'); } }); app.listen(3000, () => console.log('Server running on port 3000'));
Step 2: EJS Template (index.ejs)
Now, in your index.ejs file, we'll render the link only if we have a valid profileUrl (to avoid broken links when there are no users):
<!DOCTYPE html> <html> <head> <title>Random User Profile</title> </head> <body> <% if (profileUrl) { %> <a href="<%= profileUrl %>">Click Here To See User Profile</a> <% } else { %> <p>No users found in the database. Add some users first!</p> <% } %> </body> </html>
How to Return a String Populated by Async Variables
The key thing to remember here is that async operations don't return results immediately—you can't just write something like:
// ❌ This won't work! userIds will be a Promise, not an array const userIds = User.find({}).distinct("_id"); const randomId = _.sample(userIds);
Instead, you need to wait for the async operation to resolve before using its result:
- Use
async/await: Wrap your code in anasyncfunction, then useawaitbefore the async call (like we did in the route handler). This pauses execution until the Promise resolves, giving you the actual array of IDs. - Or use Promise chains: If you prefer not to use
async/await, you can chain.then()calls to handle the result once it's ready:app.get('/', (req, res) => { User.find({}).distinct("_id") .then(userIds => { if (userIds.length === 0) { return res.render('index', { profileUrl: null }); } const randomId = _.sample(userIds); const profileUrl = `http://localhost:9090/api/${randomId}`; res.render('index', { profileUrl }); }) .catch(error => { console.error('Error:', error); res.status(500).send('Something broke!'); }); });
Either way, you have to wait for the MongoDB query to finish before generating the URL—this ensures your randomId variable is populated with a real ID, not a pending Promise.
内容的提问来源于stack exchange,提问作者user9579936

