Open wendux opened 6 years ago
先赞为敬,顺便想问一下,对于"在响应拦截器中执行异步任务",如果在使用"新的"fly实例请求获取token之前有一个异步操作(例如微信小程序中的wx.login方法),如何处理?
@brandonhulala 如果一个同时发送两个请求,两个请求都是token过去需要重新登录获取code,那不是要登录两次吗?
@AllenForward @brandonhulala fly.lock和fly.unlock了解一下
:octocat: From gitme Android
fly.lock()不能阻止执行登录啊.
可以的,一旦调用fly.lock()
,那么后续请求都会进入一个队列。你有两个请求依赖登录,假设第一个请求先进入拦截器,然后发现没有token,然后调用fly.lock()
,那么当前fly实例被锁定,你第二个请求则会进入队列等待。然后你用新的fly实例去请求token,请求完成后调用unlock()
,第二个请求就会进入拦截器,这时token已经有了,你在将token设置到header,如示例中的request.headers["csrfToken"]=csrfToken
,那么第二个请求就可以成功。请求token只需要一次。
嗯,谢谢,这个是在请求拦截器中设置的,我这里没有问题,我的问题是在响应拦截器中,页面加载时同时请求了两个接口,两个接口返回的状态码都表示token已过期,所以我在这里判断如果状态码表示token过期的话就重新登录获取新的token,但是这里登录会执行两次,因为有两个请求的返回。
@AllenForward 响应拦截器中的话 你可以在第一次请求失败后 然后登录 登录成功后记录一个时间戳,第二个请求进入响应拦截器的话,先看看时间差是否小于一个阀值(认为已经重新登录成功)…… 注意,在响应拦截器中应该调用响应拦截器的lock和unlock方法,fly.lock和fly.unlock是请求拦截器的锁定和解锁方法。
:octocat: From gitme Android
使用场景:关键字模糊搜索,input事件不断被触发,如果前面的请求没响应,如何abort()掉?
有谁在小程序请求拦截器中遇到过wx.setStorageSync()方法不执行的问题吗.
我按照上面的例子照猫画虎,结果发现,finally并没有执行
qmRequest.interceptors.request.use(async function (request) {
const auth = wx.getStorageSync('auth')
if (auth) {
// 当前Storage中包含了auth信息,直接拿来用,不要管有没有过期,如果过期后端会告诉我们401,到时候再response的拦截器里做retry就好了.
request.headers['Authorization'] = auth
return request
} else {
// 当前Storage中未包含auth信息,是新人,走login获取进行oAuth,获取token
// 所有请求队列冻结,等待oAuth结果
qmRequest.lock()
let code = await oAuthMethods.wxLogin()
console.log('code:', code)
return oAuthRequest.post('login', {
code
})
.then((res) => {
// 获取oAuth的结果
let newAuth = `${res.data.meta.token_type} ${res.data.meta.access_token}`
wx.setStorageSync('auth', newAuth)
wx.setStorageSync('session_key', res.data.session_key)
request.headers['Authorization'] = newAuth
console.log('oAuth end')
return Promise.resolve(request)
})
.finally(() => {
// 释放后续请求
console.log('unlock')
qmRequest.unlock()
})
}
})
原来是小程序api没有finally......
@apiaoqzh finally 是promise新Api ,小程序还不支持
:octocat: From gitme Android
你在请求拦截器里面使用wx.setStorageSync同步存储在真机上面没问题吗? @apiaoqzh
@wendux 在“响应拦截器”当中,通过function(error)捕捉到<401,请登录>,代码如下:
function (error) {
if(error.status === 401) {
// console.log('先锁住请求')
this.lock();
return tokenService.login()
.then((token) => {
console.log('token已更新')
error.request.headers.Authorization = token;
})
.finally(() => {
console.log('解锁队列');
this.unlock();
})
.then(() => {
console.log('重新发起新的请求');
// 重新发起新的请求
return Rxports.ajax(error.request)
})
}
}
即使我预先调用了this.lock(),页面如果存在多个请求,则会多次调用login(),导致重复请求token的情况。
https://wendux.github.io/dist/#/doc/flyio/interceptor