使用fetch API时,.then内赋值的变量外部为空,求解决
问题分析与解决方案
问题原因
fetch 是异步操作,它不会阻塞后续代码执行。调用fetch后,JavaScript会立刻执行后面的console.log(suggestions)和for循环,此时API请求还未完成,suggestions仍为初始的空数组。只有当API请求成功返回数据时,.then里的回调函数才会触发,suggestions才会被赋值为data.results。
方案1:将DOM操作逻辑移入.then回调内部
确保数据返回后再执行列表渲染逻辑:
movieSearch(){ const div = document.getElementById("suggestionList")!; const input = <HTMLInputElement>document.getElementById("searchInput"); console.log(input.value); fetch(environment.queryByName + `&query=${input.value}`, environment.options) .then(resp => resp.json()) .then(data => { const suggestions = data.results; console.log(suggestions); // 此时数据已正常赋值 // 清空原有列表,避免重复添加条目 div.innerHTML = ''; for(let i = 0; i < suggestions.length; i++){ const node = document.createElement("li"); const text = document.createTextNode(suggestions[i].title); node.appendChild(text); div.appendChild(node); } }) .catch(err => { console.error("API请求出错:", err); }); }
方案2:使用async/await语法(更简洁直观)
将函数声明为async,用await等待异步操作完成,让代码逻辑顺序更符合直觉:
async movieSearch(){ const div = document.getElementById("suggestionList")!; const input = <HTMLInputElement>document.getElementById("searchInput"); console.log(input.value); try { const resp = await fetch(environment.queryByName + `&query=${input.value}`, environment.options); const data = await resp.json(); const suggestions = data.results; console.log(suggestions); // 清空列表 div.innerHTML = ''; for(let i = 0; i < suggestions.length; i++){ const node = document.createElement("li"); const text = document.createTextNode(suggestions[i].title); node.appendChild(text); div.appendChild(node); } } catch(err) { console.error("API请求出错:", err); } }
额外建议(Angular最佳实践)
直接操作DOM不符合Angular组件化思路,推荐用Angular原生方式处理:
- 使用
@ViewChild获取DOM元素,替代document.getElementById:
import { ViewChild, ElementRef } from '@angular/core'; // 组件类内部 @ViewChild('suggestionList') suggestionList!: ElementRef<HTMLUListElement>;
模板中添加模板引用变量:
<ul #suggestionList></ul>
- 定义组件属性存储建议列表,用
*ngFor在模板中自动渲染,彻底避免手动操作DOM:
// 组件类属性 suggestions: any[] = []; async movieSearch(){ const input = <HTMLInputElement>document.getElementById("searchInput"); try { const resp = await fetch(environment.queryByName + `&query=${input.value}`, environment.options); const data = await resp.json(); this.suggestions = data.results; } catch(err) { console.error("API请求出错:", err); } }
模板修改为:
<div class="searchSuggestion"> <ul> <li *ngFor="let item of suggestions">{{item.title}}</li> </ul> </div>
内容的提问来源于stack exchange,提问作者Gabriel Evaristo
相关产品推荐
相关产品推荐

