为什么lyrics变量在async/await函数外返回空字符串
问题原因
- JavaScript中
async函数执行时遇到await关键字会暂时让出主线程,继续执行函数体外的后续同步代码,等到await后的异步操作执行完成后,才会回到async函数内部执行剩下的逻辑 - 你代码的实际执行顺序如下:
- 初始化
lyrics为空字符串 - 调用
displayLyrics2(),函数执行到await fetch(url)时暂停,主线程继续往下执行后续同步代码 - 执行外层的
console.log(lyrics),此时fetch请求还没返回结果,lyrics还是初始的空值 - 后续fetch请求完成、拿到接口返回值后,才会执行
lyrics+= response.result.lyrics的赋值逻辑,因此只有函数内部的打印能拿到正确值
- 初始化
注意:你原有代码调用
displayLyrics2时没有传入需要的url参数,实际使用时需要传入正确的接口地址,否则fetch会直接报错。
修复方案
方案1:所有依赖lyrics的逻辑都放到async函数内部
所有需要用到歌词的处理逻辑(比如渲染到页面、后续格式处理等)都写在异步函数内部,保证赋值完成后再执行对应逻辑:
async function displayLyrics2(url){ const request = await fetch(url); const response = await request.json(); const lyrics = response.result.lyrics; // 所有用到lyrics的逻辑都写在这里 console.log(lyrics); } displayLyrics2('你的实际接口地址')
方案2:外层用await等待异步函数执行完成
需要把外层的逻辑放到另一个async作用域中,等待displayLyrics2执行完成后再读取lyrics的值:
let lyrics = ''; async function displayLyrics2(url){ const request = await fetch(url); const response = await request.json(); lyrics += response.result.lyrics; } // 用自执行async函数包裹 (async () => { await displayLyrics2('你的实际接口地址'); // 等待异步操作完成后再打印,就能拿到正确值 console.log(lyrics) })()
方案3:用Promise.then回调处理
利用async函数默认返回Promise的特性,在then回调中处理赋值后的歌词:
let lyrics = ''; async function displayLyrics2(url){ const request = await fetch(url); const response = await request.json(); lyrics += response.result.lyrics; return lyrics; } displayLyrics2('你的实际接口地址').then(lyrics => { // 回调内可以拿到正确的lyrics值 console.log(lyrics) })
内容的提问来源于stack exchange,提问作者BigDaddyTrump
相关产品推荐
相关产品推荐

