平时开发里,先请求一个 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