平時開發裏,先請求一個 token ,而後後面的請求都要帶上這個 token 來進行認證或者受權,是一個常見的需求css
那要怎麼搞呢?仍是一個前後,控制異步流程的的問題,就是先拿到 token 再進行後面的請求就行了。相信 promise 你們已經用得很氾濫了:jquery
let tokenPromise = new Promise(...) // 拿到 token tokenPromise.then()... // 拿到 token 後去拿數據1 tokenPromise.then()... // 拿到 token 後去拿數據2 tokenPromise.then()... // 拿到 token 後去拿數據3 ...
若是向上面這樣組織那就徹底沒問題了。可是實際上通常也不會這樣寫吧,好蠢。。。可是計算機就是用來幫咱們作這種蠢的重複性工做的,咱們稍微變通一下,原理仍是同樣,只是代碼寫好看或者寫少一點就行了ios
假設咱們都是用 XMLHttpRequest 來發起請求的話(誰能告訴我爲何XML是大寫Http卻不是。。。),咱們能夠在 xhr.send()
上作點手腳,把這個函數再包多一層,在裏面叫它幫咱們調用 tokenPromise.then()
。先作好準備工做:git
首先我先用 easy-mock 模擬了兩個接口,一個返回 token,一個返回 messagegithub
https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/token { "data": { "token": "a_mock_token" } } https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/message { "data": { "message": "你好" } }
而後用 jQuery 的 ajax 發請求(只要是用了 XMLHttpRequest 對象,都ok):ajax
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
接下來能夠寫代碼了axios
// 先拿 token var tokenPromise = new Promise((resovle, reject) => { // 清除緩存裏的token localStorage.removeItem('token') $.ajax({ type: 'GET', url: 'https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/token', success(res) { let token = res.data.token localStorage.setItem('token', token) resovle(token) }, fail(err) { reject(err) } }) }) // 對 xhr.send 再包多一層 var originSend = XMLHttpRequest.prototype.send XMLHttpRequest.prototype.send = function () { var args = arguments var self = this var fn = function () { var token = localStorage.getItem('token') // 假如把 token 放在請求頭裏 self.setRequestHeader('token', token) console.log('後續請求token: ', token) originSend.apply(self, args) } // tokenPromise resolved 了纔會執行後續的請求 tokenPromise.then(fn) } // 後續其餘請求, Network 看一下,請求已經帶上 token 了 $.ajax({ type: 'GET', url: 'https://easy-mock.com/mock/5b8fea568eee36669a6b5523/example/message', success(res) { console.log(res) }, fail(err) { console.log(err) } })
完整的代碼小程序
固然這只是一個大概的思路,你要用 axios 而不用 $.ajax ,或者是在小程序裏對 wx.request() 包多一層而不是對 xhr.send() 包多一層都是相似的。但願咱們能寫出更多野雞的寫法promise
最近在認真學習 promise,以爲 史上最易讀懂的 Promise/A+ 徹底實現 這篇文章真的挺棒的,起碼能看懂一點了緩存
而後有看到 fly (一個相似於axios的ajax庫)直接就把咱們上述這個先請求 token 的功能寫在文檔裏了,而且這個做者還寫了一個 Ajax-hook 來攔截 ajax 請求
因此就強行給博客拔拔草 :D