Clients need to update token from time to time, while ensuring that other network requests hang while sending update token, otherwise token will fail. When the new token returns, the pending request is re-initiated.
Update the token request at the request of the server, and the old token expires immediately
Catalog
Analog Network Request Encapsulation (Analog)
let token = 1 The current request uses token let refreshToken = false // Is it in the update token let subscribers = []; // Suspended request array /** * Network request entry */ function callApi (data, time = 1000) { console.log('0000callApi=== type:' + data.type + ' token:' + token) if (refreshToken) { const retryOriginalRequest = new Promise((resolve) => { addSubscriber(()=> { resolve(request(time, data.type)) }) }); return retryOriginalRequest; } // Determine whether the update token is executed if (data && (data.type == 'refreshToken')) { const newData = request(time, data.type) refreshToken = true return newData } return request(time, data.type) } /** * Perform network requests */ function request(ms, type) { console.log('1111request=== type:' + type + ' token:' + token) return new Promise((resolve, reject) => { setTimeout(resolve, ms, type); }); } /** * token Update, restart pending requests */ function onAccessTokenFetched() { subscribers.forEach((callback)=>{ console.log('Re request') callback(); }) refreshToken = false subscribers = []; } /** * push Suspended requests * @param callback Suspended requests */ function addSubscriber(callback) { subscribers.push(callback) }
Use demonstrations:
// before callApi({type: 'first', token}, 1000).then(consoleResponse) // Todo callApi({type: 'refreshToken', token}, 2000).then((v) => { token = 2 onAccessTokenFetched() consoleResponse(v) }) // doing callApi({type: 'second', token}, 2000).then(consoleResponse) callApi({type: 'third', token}, 2000).then(consoleResponse) callApi({type: 'four', token}, 2000).then(consoleResponse) callApi({type: 'five', token}, 2000).then(consoleResponse) // after setTimeout(() => callApi({type: 'six', token}, 2000).then(consoleResponse), 5000) function consoleResponse (v) { console.log('2222response===type:' + v + ' token:' + token) }
Result printing
"0000callApi=== type:first token:1" "1111request=== type:first token:1" "0000callApi=== type:refreshToken token:1" "1111request=== type:refreshToken token:1" "0000callApi=== type:second token:1" "0000callApi=== type:third token:1" "0000callApi=== type:four token:1" "0000callApi=== type:five token:1" "2222response===type:first token:1" "Re request" "1111request=== type:second token:2" "Re request" "1111request=== type:third token:2" "Re request" "1111request=== type:four token:2" "Re request" "1111request=== type:five token:2" "2222response===type:refreshToken token:2" "2222response===type:second token:2" "2222response===type:third token:2" "2222response===type:four token:2" "2222response===type:five token:2" "0000callApi=== type:six token:2" "1111request=== type:six token:2" "2222response===type:six token:2"
Summary
- This case is mainly a simulation process, which is the idea of encapsulating the network request for this transformation. It does not give much advice to the local gods.
- In the real process of network request, <font color=red> needs to deal with request timeout and request error </font>. Both timeout and error need to reset the update token identifier and restart the pending network request.