You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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原生方式处理:

  1. 使用@ViewChild获取DOM元素,替代document.getElementById:
import { ViewChild, ElementRef } from '@angular/core';

// 组件类内部
@ViewChild('suggestionList') suggestionList!: ElementRef<HTMLUListElement>;

模板中添加模板引用变量:

<ul #suggestionList></ul>
  1. 定义组件属性存储建议列表,用*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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:03:25