调用Superhero API获取图片显示破损,全局变量为何未生效?
问题解析:全局变量无法获取异步请求结果的原因
用户提供的代码
HTML代码
<body> <div id='heroImage'><img src='' alt=''></div> <button id='newHero'>Get New Hero</button> <script src="script.js"></script> </body>
JavaScript代码
const img='' let getSuperHero=(id)=>{ const newHeroDiv=document.getElementById('newHero') const heroImageDiv=document.getElementById('heroImage') let img; fetch(`https://superheroapi.com/api.php/5930076870393724/${id}`) .then(response => response.json()) .then(json => { img=json.image.url console.log(img) }) } getSuperHero(300) document.querySelector('body').innerHTML += `<img src= '${img}' height=300 width=300>`
问题描述
上述代码运行后显示破损图片。已知将最后一行DOM拼接代码放入getSuperHero函数内即可正常显示,但因已在函数外声明全局变量img,疑惑为何在函数外使用该变量无法生效。
原因及修复
核心问题有两个
- 异步操作的执行顺序:
fetch是异步请求,JS调用getSuperHero(300)后,不会等着请求返回结果,而是立刻执行后面的DOM拼接代码。这时候全局的img还是初始的空字符串,自然加载不出图片。 - 变量遮蔽:你在
getSuperHero函数内部又声明了let img;,这会覆盖全局的img变量。也就是说,你在then回调里赋值的img只是函数内部的局部变量,根本没修改到全局的那个img。
两种修复方式
方式一:修正变量作用域 + 保证异步执行顺序
删掉函数内部的let img;,让回调里赋值的是全局变量,同时用async/await确保DOM操作在请求完成后执行:let img = '' let getSuperHero = async (id) => { const response = await fetch(`https://superheroapi.com/api.php/5930076870393724/${id}`) const json = await response.json() img = json.image.url } // 用自执行异步函数确保顺序 (async () => { await getSuperHero(300) document.querySelector('body').innerHTML += `<img src='${img}' height=300 width=300>` })()方式二:直接在异步回调里操作DOM
这是最直接的办法,把DOM拼接代码放到then回调里,不需要依赖全局变量,逻辑更清晰:let getSuperHero = (id) => { fetch(`https://superheroapi.com/api.php/5930076870393724/${id}`) .then(response => response.json()) .then(json => { document.querySelector('body').innerHTML += `<img src='${json.image.url}' height=300 width=300>` }) } getSuperHero(300)
内容的提问来源于stack exchange,提问作者Lakindu Wickramaratne
相关产品推荐
相关产品推荐

