JavaScript:如何在异步函数作用域外使用其内部声明的变量
问题结论
直接在async异步函数的作用域外访问其内部fetch获取后声明的变量,现有写法完全不可行,核心原因有两个:
- 作用域天生隔离:在
getCredits函数内部用const声明的directors、directorsName属于函数局部作用域,外部代码本身没有权限访问,和函数是否异步无关。就算是完全同步的普通函数,外部也无法直接读取内部的局部变量。 - 异步时序不匹配:调用
getCredits(CREDITS_URL)后,代码不会阻塞等待内部await fetch的网络请求完成,会立刻向下执行创建卡片的逻辑。这时候哪怕把变量声明到外部作用域,拿到的也只是还没被赋值的初始空值。
适配现有逻辑的修改方案
完成两个调整即可解决问题:
- 改造
getCredits函数,把处理完成的directorsName作为函数的返回值,而非在内部定义完就丢弃。 - 将
forEach的回调改为async函数,调用getCredits时用await等待接口返回结果,拿到directorsName之后再执行卡片创建、插入DOM的逻辑。
修正后的参考代码:
movies.forEach(async (movie) => { const { title, poster_path, vote_average, overview, release_date, id } = movie const CREDITS_URL = `the credits url goes here and it uses this -> ${id}` async function getCredits(url) { const res = await fetch(url) const data = await res.json() // 从接口返回的演职人员数据中过滤出导演,逻辑根据实际接口字段调整 const directors = data.crew.filter(person => person.job === "Director") // 处理完成后返回拼接好的导演名字符串 return directors.map(item => item.name).join(", ") } // 等待接口返回拿到最终的directorsName const directorsName = await getCredits(CREDITS_URL) const card = document.createElement("div") card.innerHTML = ` <div class="director"> <h3>Directed by ${directorsName}</h3> </div> ` cards.appendChild(card) })
补充说明
如果电影列表规模较大,循环内并发发起所有credits接口请求可能会给后端造成压力,后续可根据需求增加请求并发限制,该调整不影响当前变量访问问题的解决逻辑。
内容的提问来源于stack exchange,提问作者eren
相关产品推荐
相关产品推荐

