JavaScript异步函数无法获取jsonplaceholder数据,DOM无法渲染内容
解决JavaScript异步请求jsonplaceholder API失败及DOM渲染问题
问题根源
- 无效的API地址:
obtenerComentarios函数中使用了占位符URL,无法发起有效请求 - 字段匹配错误:jsonplaceholder的评论接口返回数据不含
userId字段,原代码无法通过该字段筛选作者对应的评论;评论通过postId关联文章,文章通过userId关联用户,需通过这个关联关系实现筛选
修正后的完整代码
HTML(无需修改,保持原结构即可)
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blog - Lista de Comentarios</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .flex { display: flex; flex-wrap: wrap; } .flex article { width: calc(50% - 20px); margin: 10px; padding: 10px; border: 2px solid black; } .flex article:nth-child(even) { background-color: #f0f0f0; } select { border: 2px solid tomato; width: 80%; padding: 20px; margin: 20px auto 0px auto; display: block; font-size: 150%; } hr { margin: 20px; } </style> </head> <body> <header> <select id="selectAutor"> <option value="" selected>Selecciona un autor</option> <option value="1">Autor 1</option> <option value="2">Autor 2</option> <option value="3">Autor 3</option> <!-- Añadir más opciones según sea necesario --> </select> <hr> </header> <section id="comentarios" class="flex"> <!-- esta es la superficie iterable que hay que repetir por cada comentario --> <article> <h3>Nombre del autor</h3> <p>Email: correo@dominio.com</p> <p>Comentario:</p> <p>Texto del comentario</p> </article> </section> <script src="script.js"></script> </body> </html>
JavaScript
document.addEventListener('DOMContentLoaded', () => { // 缓存已获取的数据,避免重复请求API let comentariosCache = null; let postsCache = null; // 获取所有文章(用于关联用户与评论) async function obtenerPosts() { if (postsCache) return postsCache; const url = 'https://jsonplaceholder.typicode.com/posts'; try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP错误!状态码:${response.status}`); postsCache = await response.json(); return postsCache; } catch (error) { console.error('获取文章失败:', error); throw error; } } // 获取所有评论 async function obtenerComentarios() { if (comentariosCache) return comentariosCache; const url = 'https://jsonplaceholder.typicode.com/comments'; try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP错误!状态码:${response.status}`); comentariosCache = await response.json(); return comentariosCache; } catch (error) { console.error('获取评论失败:', error); throw error; } } // 筛选指定用户的所有评论 async function obtenerComentariosPorAutor(idAutor) { const posts = await obtenerPosts(); const comentarios = await obtenerComentarios(); // 先获取该用户发布的所有文章ID const userPostIds = posts.filter(post => post.userId === idAutor).map(post => post.id); // 筛选出关联这些文章的评论 return comentarios.filter(comentario => userPostIds.includes(comentario.postId)); } // 渲染指定用户的评论到DOM async function mostrarComentariosPorAutor(idAutor) { console.log('选中的作者ID:', idAutor); try { const comentariosAutor = await obtenerComentariosPorAutor(idAutor); console.log('该作者的评论:', comentariosAutor); const contenedorComentarios = document.getElementById('comentarios'); contenedorComentarios.innerHTML = ''; // 处理无评论的情况 if (comentariosAutor.length === 0) { contenedorComentarios.innerHTML = '<p>该作者暂无评论内容</p>'; return; } comentariosAutor.forEach(comentario => { const article = document.createElement('article'); article.innerHTML = ` <h3>${comentario.name}</h3> <p>邮箱: ${comentario.email}</p> <p>评论内容:</p> <p>${comentario.body}</p> `; contenedorComentarios.appendChild(article); }); } catch (error) { console.error('渲染评论失败:', error); document.getElementById('comentarios').innerHTML = '<p>加载评论时发生错误,请稍后重试</p>'; } } // 监听作者选择下拉框的变化事件 document.getElementById('selectAutor').addEventListener('change', event => { const idAutor = parseInt(event.target.value); if (idAutor) { mostrarComentariosPorAutor(idAutor); } else { // 选择空选项时重置为初始状态 document.getElementById('comentarios').innerHTML = ` <article> <h3>Nombre del autor</h3> <p>Email: correo@dominio.com</p> <p>Comentario:</p> <p>Texto del comentario</p> </article> `; } }); });
关键优化点
- 替换占位符为jsonplaceholder的真实API地址,确保请求有效
- 新增文章数据获取逻辑,通过
文章-用户、评论-文章的关联关系实现按用户筛选评论 - 加入数据缓存机制,避免重复请求API,提升页面性能
- 增加HTTP请求状态校验,处理请求失败的场景
- 补充空数据和错误状态的DOM提示,提升用户体验
- 优化空选项选择时的页面重置逻辑
内容的提问来源于stack exchange,提问作者Daniel Fenoll
相关产品推荐
相关产品推荐

