首页 > 代码库 > 一篇知乎的故事 - javascript技术贴

一篇知乎的故事 - javascript技术贴

前言  

  就像文章题目所示,本文的发表源于知乎的一篇文章。文章链接如下:如果你想靠前端技术还房贷,你不能连这个都不会。这篇文章是群里水群时别人发的,像我这样的菜鸟角色才不会逛知乎~~~。这篇文章主要是讲了一个面试官面试前端的一个他自己的感触,作者生动形象(这个词中学语文哪个试卷没写过?)的描述了当下的前端开发者的水平低低低,当然不是说我们水平低,是他面试的那些人的水平。。他在文章的两个题,我觉得第二个还是很有意思的,由此发此文章。

题外话:昨天晚上被老板深深的训斥了,表示我太懒了,不动脑子不积极作业,老是想着让别人教,拿现成的。咋办,博主太懒了是不假。新手入职,刚来实习,第一周就被微信开发,看着微信开发者文档,我勒个去,太官方了,无法理解,踩了好多坑,在自定义菜单那里,静默授权,等等,反正,第一次接触,又没有开发经验,都稀里糊涂的,我本身是前端,对后台的思想太欠缺了,虽然后台是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=http://www.mamicode.com/"https://unpkg.com/vue/dist/vue.js"></script>
//    resource.min.js  自己下载的
<script type="text/javascript" src=http://www.mamicode.com/"./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 =http://www.mamicode.com/ res.data
                this.ajax2()
              })
            },
            request2: function () {
              this.ajax2 = function () {
                var url = 我的测试地址:睡眠1秒返回值
                this.$http.get(url).then(function(res)  {
                  this.inputData =http://www.mamicode.com/ 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=http://www.mamicode.com/"https://unpkg.com/vue/dist/vue.js"></script>
  <script type="text/javascript" src=http://www.mamicode.com/"./vue-resource.min.js"></script>
  <script type="text/javascript" src=http://www.mamicode.com/"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 =http://www.mamicode.com/ 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技术贴