一篇知乎的故事 - javascript技術貼

前言  

  就像文章題目所示,本文的發表源於知乎的一篇文章。文章連接以下:若是你想靠前端技術還房貸,你不能連這個都不會。這篇文章是羣裏水羣時別人發的,像我這樣的菜鳥角色纔不會逛知乎~~~。這篇文章主要是講了一個面試官面試前端的一個他本身的感觸,做者生動形象(這個詞中學語文哪一個試卷沒寫過?)的描述了當下的前端開發者的水平低低低,固然不是說咱們水平低,是他面試的那些人的水平。。他在文章的兩個題,我以爲第二個仍是頗有意思的,由此發此文章。javascript

題外話:昨天晚上被老闆深深的訓斥了,表示我太懶了,不動腦子不積極做業,總是想着讓別人教,拿現成的。咋辦,博主太懶了是不假。新手入職,剛來實習,第一週就被微信開發,看着微信開發者文檔,我勒個去,太官方了,沒法理解,踩了好多坑,在自定義菜單那裏,靜默受權,等等,反正,第一次接觸,又沒有開發經驗,都稀裏糊塗的,我自己是前端,對後臺的思想太欠缺了,雖而後臺是nodejs,可是仍是不懂啊,畢竟服務端。搞了一週才差很少完成了當前須要的微信開發者功能。本想開寫寫微信開發的坑,哪些功能須要怎麼設置之類的,看到這篇知乎就成了發此文。

前提

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 的博客園

感謝閱讀

  留下本身的每個腳印,將來不論是成功仍是失敗,這都是一份回憶。

相關文章
相關標籤/搜索