JavaScript中Spotify API请求同步问题:Token刷新与流派获取
解决Spotify API令牌同步问题
问题根源
getToken函数中的fetch是异步操作,调用getToken()后立刻执行getGenres()时,新令牌还未写入localStorage,导致第二次getGenres拿到的仍是无效或空令牌,请求依旧失败。
解决思路
- 让
getToken返回Promise,确保调用方可以等待令牌获取/验证完成 - 在
getGenres处理401错误时,等待新令牌生成后再重新发起请求 - 统一
getToken的返回行为,无论是否已有令牌都返回Promise
修改后的代码
重构getToken函数
function getToken() { const existingToken = localStorage.getItem("sessionToken"); if (existingToken) { return Promise.resolve(existingToken); } return fetch(url, { method: "POST", headers: { Authorization: "Basic " + btoa(`${clientId}:${clientSecret}`), "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ grant_type: "client_credentials" }), }) .then(response => response.json()) .then(tokenResponse => { localStorage.setItem("sessionToken", tokenResponse.access_token); return tokenResponse.access_token; }); }
重构getGenres函数(使用async/await简化异步流程)
async function getGenres() { let sessionToken = localStorage.getItem("sessionToken"); try { const response = await fetch(`${BASE}/recommendations/available-genre-seeds`, { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer " + sessionToken, }, }); if (!response.ok) { const data = await response.json(); if (data.error.status === 401) { localStorage.removeItem("sessionToken"); await getToken(); return getGenres(); } else { throw new Error(`请求失败: ${data.error.message}`); } } const genres = await response.json(); showGenres(genres); } catch (error) { console.error("获取流派失败:", error); } }
关键优化点
getToken现在始终返回Promise,保证异步流程的一致性getGenres改为async函数,用await替代嵌套的.then,代码可读性更强- 401错误处理时,等待新令牌写入localStorage后再重新请求,确保拿到有效令牌
- 增加全局错误捕获,处理网络异常等其他错误场景
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

