ReactJs中如何封装Token生成函数并将返回值传递给后续请求
实现方案
你不需要强行同步获取Promise的返回值,异步逻辑只要做好统一封装,完全可以实现Token请求逻辑的全局复用,不需要每次嵌套写重复代码。
第一步:封装独立可复用的Token获取函数
把Token请求逻辑抽成全局公共方法,方法内部直接返回Promise链,最终resolve的值就是生成好的Token字符串:
const fetchToken = () => { return fetch('/api/token', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ id: '5' }), }) .then(response => response.json()) .then(res => res.token) }
第二步:在任意业务请求中调用该方法
有两种常用写法,都不需要嵌套多层回调:
Promise链式调用写法
拿到Token后在链式调用里发业务请求即可,记得return内部的fetch请求,保持链式调用的扁平化,同时统一加错误捕获:// 示例:获取评论列表的业务请求 fetchToken() .then(token => { return fetch('/api/reviews', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ limit: 10 }), }) }) .then(response => response.json()) .then(result => { this.setState({ data: result.data }) }) .catch(err => { console.error('请求异常:', err) })async/await 写法(推荐)
用async/await语法可以让异步代码写起来和同步逻辑一致,完全没有嵌套,可读性更高:// 业务请求方法 const loadReviewData = async () => { try { // 等待Token生成完成 const token = await fetchToken() // 发起业务请求 const reviewResp = await fetch('/api/reviews', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ limit: 10 }), }) const result = await reviewResp.json() this.setState({ data: result.data }) } catch (err) { console.error('请求异常:', err) } } // 需要触发请求的地方直接调用即可 loadReviewData()
可选优化:避免重复请求
如果短时间内会触发多个带Token的业务请求,可以给Token方法加简单的请求缓存,同一时间内多个调用复用同一个Token请求,避免重复调用Token接口:
// 缓存正在进行的Token请求 let pendingTokenRequest = null const fetchToken = () => { // 已有正在进行的请求时直接返回,不重复发起 if (pendingTokenRequest) return pendingTokenRequest pendingTokenRequest = fetch('/api/token', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ id: '5' }), }) .then(response => response.json()) .then(res => { pendingTokenRequest = null // 请求完成后清空缓存 return res.token }) .catch(err => { pendingTokenRequest = null // 请求失败也要清空缓存,避免阻塞后续调用 throw err }) return pendingTokenRequest }
封装完成后,不管后续业务请求的逻辑、地址、参数有什么差异,只要先调用fetchToken()拿到Token,再注入对应请求的鉴权头即可,不需要重复写Token请求的代码。
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

