就像文章題目所示,本文的發表源於知乎的一篇文章。文章連接以下:若是你想靠前端技術還房貸,你不能連這個都不會。這篇文章是羣裏水羣時別人發的,像我這樣的菜鳥角色纔不會逛知乎~~~。這篇文章主要是講了一個面試官面試前端的一個他本身的感觸,做者生動形象(這個詞中學語文哪一個試卷沒寫過?)的描述了當下的前端開發者的水平低低低,固然不是說咱們水平低,是他面試的那些人的水平。。他在文章的兩個題,我以爲第二個仍是頗有意思的,由此發此文章。javascript
1. 本文是一個vue的小組件功能,你須要有vue的經驗,而且瞭解vue的組件。html
2. 本文會貼出一個盜版的jQuery.queue函數,這個函數是以前讀jq源碼本身寫的,就是偷得jq,比不上jq強大,可是基本功能仍是有的。前端
3. 本文不適合新手哦,若是你是個編程新手,你是看不懂的哦。vue
注意: 本文的測試路徑沒有給出,怕有黑老大把個人服務器搞崩了。java
上面是問題,咱們來解讀一下需求:node
1. 首先要有一個模塊,這個模塊包括一個input,兩個buttonjquery
2. 模塊實現了點擊 A,發送urlA請求,並將input值改成請求返回的值,點擊B,雷同git
3. 用戶依次點擊A、B,input首先須要改成urlA請求返回的值,再改成urlB返回的值。也就相似於同步請求。面試
<div id="app"> <my-component></my-component> </div> <template id="tpl"> <div> <input type="text" v-model="inputData" readonly="readonly"> <p> <button @click="request1">按鈕A</button> <button @click="request2">按鈕B</button> </p> </div> </template> <script src="https://unpkg.com/vue/dist/vue.js"></script> // resource.min.js 本身下載的 <script type="text/javascript" src="./resource.min.js"></script> <script> Vue.use(VueResource) new Vue({ el: '#app', components: { 'my-component': { template: '#tpl', data: function () { return { inputData: '默認的', ajax2: null } }, methods: { request1: function () { var url = '個人測試地址:睡眠2秒再返回值' this.$http.get(url).then(function(res) { this.inputData = res.data this.ajax2() }) }, request2: function () { this.ajax2 = function () { var url = '個人測試地址:睡眠1秒返回值' this.$http.get(url).then(function(res) { this.inputData = res.data }) } }, }, } } }) </script>
我定義了一個vue實例,在#app元素內有效。定義個組件,給這個組件一個inputData屬性存儲input框中的數據,定義一個ajax2屬性存儲點擊B按鈕時的發起請求的函數。咱們在點擊A後返回值後,調用ajax2這個方法,這樣就實現了上面的需求,固然僅僅是實現了上面的需求而已,而且代碼看上去很難看,由於咱們爲了實現這個功能不得不在模型上加了個ajax2這個很雞肋的中間量,爲了讓代碼更好看一些,功能更強一些,不防試一試用隊列來解決。ajax
咱們不只要實現上面這個簡單的例子,咱們須要實現的效果更強壯:
1. 連續交替點擊A、B按鈕,將返回值有順序的顯示到input上面
2. 每一次點擊都會產生一個ajax請求,可是不會馬上發起,會根據點擊順序依次請求。
3. 利用一個隊列對象來實現,使代碼變得更簡潔更美觀。
代碼以下:
<div id="app"> <my-component :q="q"></my-component> </div> <template id="tpl"> <div> <input type="text" v-model="inputData" readonly="readonly"> <p> <button @click="request('測試地址1:睡眠2秒')">按鈕A</button> <button @click="request('測試地址2:睡眠1秒')">按鈕B</button> </p> </div> </template> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript" src="./vue-resource.min.js"></script> <script type="text/javascript" src="http://git.oschina.net/xuazheng/myJquery/raw/master/queue/queue.js?dir=0&filepath=queue%2Fqueue.js&oid=b23c3bf7212ff41aad350bdb505a1afc59929ce6&sha=d0298a8907c9ed1cf25c176807fadbcd14c3e571"></script> <script type="text/javascript"> Vue.use(VueResource) new Vue({ el: '#app', data: { q: Queue() }, components: { 'my-component': { template: '#tpl', data: function () { return { inputData: '默認的' } }, methods: { request: function (url) { this.q.queue('fx', function (next){ this.$http.get(url).then(function(res) { this.inputData = res.data next() }) }.bind(this)) } }, props: ['q'] }, } }) </script>
引入了個人queue,在vue實例上,建立一個q屬性存儲queue對象並傳遞給子組件。在子組件中,咱們每次點擊一個按鈕,都會將一個ajax請求的函數添加到fx隊列中,在jquery中,fx類型的隊列存儲着動畫函數,能夠處理異步函數隊列的有序執行。不傳遞這個值會默認fx類型,因此也能夠直接在queue方法中傳遞一個方法就行。
因此,咱們利用了隊列來完善了咱們的需求,太棒了。
;function Queue() { // 數據緩存對象 var cache = {}; var queueList = { // type默認是fx,是動畫隊列 queue: function(type,data) { var args = arguments; //沒有參數直接返回 if(!args.length){ return; } var q = null; // 只有一個參數而且是個函數 if(args.length == 1 && typeof type === 'function') { data = type; type = 'fx'; } q = cache[type] || []; // 添加緩存 if( data instanceof Array) { q = data; }else { q.push(data) } cache[type] = q; //若是是動畫隊列而且沒有開始的動畫,執行第一個動畫函數 if(type == 'fx' && q.toString().indexOf('inprogress') === -1) { queueList.dequeue() } return q; }, dequeue: function(type) { var fn, queue; type = type || 'fx'; queue = cache[type]; if(queue.length == 0 ) { return; } fn = queue.shift(); if( fn === 'inprogress' ) { fn = queue.shift(); } if( fn ) { if(type === 'fx') { queue.unshift('inprogress'); } fn.call(null,function() { queueList.dequeue(type); }) } }, // 延遲使用setTimeout來實現 delay: function(type,timeout) { if(!type) { return; } if(arguments.length == 1) { timeout = type; type = 'fx'; } if(typeof timeout == 'number') { var q = cache[type]; if(!q) { q = cache[type] = [_delay]; }else { q.push(_delay) } } function _delay() { setTimeout(queueList.dequeue, timeout); } return this; }, get: function(type) { type = type || 'fx'; return cache[type]; } } return queueList; }
這個就不解釋了,比起jquery源碼,這個代碼就顯得很簡單,jquery中作了大量的處理,然而博主並無那麼厲害,只能簡單的寫了這點。有js基礎的應該看得懂,若是想學jq源碼,推薦 艾倫 Aaron 的博客園。
留下本身的每個腳印,將來不論是成功仍是失敗,這都是一份回憶。