標籤:失敗 函數 發送 傳回值 nodejs 菜鳥 ima 表示 產生
前言
就像文章題目所示,本文的發表源於知乎的一篇文章。文章連結如下:如果你想靠前端技術還房貸,你不能連這個都不會。這篇文章是群裡水群時別人發的,像我這樣的菜鳥角色才不會逛知乎~~~。這篇文章主要是講了一個面試官面試前端的一個他自己的感觸,作者生動形象(這個詞中學語文哪個試卷沒寫過?)的描述了當下的前端開發人員的水平低低低,當然不是說我們水平低,是他面試的那些人的水平。。他在文章的兩個題,我覺得第二個還是很有意思的,由此發此文章。
題外話:昨天晚上被老闆深深的訓斥了,表示我太懶了,不動腦子不積極作業,老是想著讓別人教,拿現成的。咋辦,博主太懶了是不假。新手入職,剛來實習,第一周就被開發,看著開發人員文檔,我勒個去,太官方了,無法理解,踩了好多坑,在自訂菜單那裡,靜默授權,等等,反正,第一次接觸,又沒有開發經驗,都稀裡糊塗的,我本身是前端,對背景思想太欠缺了,雖然後台是nodejs,但是還是不懂啊,畢竟服務端。搞了一周才差不多完成了當前需要的開發人員功能。本想開寫寫開發的坑,哪些功能需要怎麼設定之類的,看到這篇知乎就成了發此文。前提
1. 本文是一個vue的小工具功能,你需要有vue的經驗,並且瞭解vue的組件。
2. 本文會貼出一個盜版的jQuery.queue函數,這個函數是之前讀jq源碼自己寫的,就是偷得jq,比不上jq強大,但是準系統還是有的。
3. 本文不適合新手哦,如果你是個編程新手,你是看不懂的哦。
注意: 本文的測試路徑沒有給出,怕有黑老大把我的伺服器搞崩了。
切入本文
上面是問題,我們來解讀一下需求:
1. 首先要有一個模組,這個模組包括一個input,兩個button
2. 模組實現了點擊 A,發送urlA請求,並將input值改為請求返回的值,點擊B,雷同
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這個很雞肋的中間量,為了讓代碼更好看一些,功能更強一些,不防試一試用隊列來解決。
隊列的作用
我們不僅要實現上面這個簡單的例子,我們需要實現的效果更強壯:
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 的部落格園。
感謝閱讀
留下自己的每一個腳印,未來不管是成功還是失敗,這都是一份回憶。
一篇知乎的故事 - javascript技術貼