前言  

本文的发表源于知乎的一篇文章。文章链接如下:如果你想靠前端技术还房贷,你不能连这个都不会

前提

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返回的值。也就类似于同步请求。

代码如下:

  1. <div id="app">
  2. <my-component></my-component>
  3. </div>
  4. <template id="tpl">
  5. <div>
  6. <input type="text" v-model="inputData" readonly="readonly">
  7. <p>
  8.  
  9. <button @click="request1">按钮A</button>
  10. <button @click="request2">按钮B</button>
  11. </p>
  12. </div>
  13. </template>
  14.  
  15. <script src="https://unpkg.com/vue/dist/vue.js"></script>
  16. // resource.min.js 自己下载的
  17. <script type="text/javascript" src="./resource.min.js"></script>
  18.  
  19. <script>
  20. Vue.use(VueResource)
  21. new Vue({
  22. el: '#app',
  23. components: {
  24. 'my-component': {
  25. template: '#tpl',
  26. data: function () {
  27. return {
  28. inputData: '默认的',
  29. ajax2: null
  30. }
  31. },
  32. methods: {
  33. request1: function () {
  34. var url = '我的测试地址:睡眠2秒再返回值'
  35. this.$http.get(url).then(function(res) {
  36. this.inputData = res.data
  37. this.ajax2()
  38. })
  39. },
  40. request2: function () {
  41. this.ajax2 = function () {
  42. var url = '我的测试地址:睡眠1秒返回值'
  43. this.$http.get(url).then(function(res) {
  44. this.inputData = res.data
  45. })
  46. }
  47. },
  48. },
  49. }
  50. }
  51. })
  52. </script>

我定义了一个vue实例,在#app元素内有效。定义个组件,给这个组件一个inputData属性存储input框中的数据,定义一个ajax2属性存储点击B按钮时的发起请求的函数。我们在点击A后返回值后,调用ajax2这个方法,这样就实现了上面的需求,当然仅仅是实现了上面的需求而已,并且代码看上去很难看,因为我们为了实现这个功能不得不在模型上加了个ajax2这个很鸡肋的中间量,为了让代码更好看一些,功能更强一些,不防试一试用队列来解决。

队列的作用

我们不仅要实现上面这个简单的例子,我们需要实现的效果更强壮:

1. 连续交替点击A、B按钮,将返回值有顺序的显示到input上面

2. 每一次点击都会产生一个ajax请求,但是不会立刻发起,会根据点击顺序依次请求。

3. 利用一个队列对象来实现,使代码变得更简洁更美观。

代码如下:

  1. <div id="app">
  2. <my-component :q="q"></my-component>
  3. </div>
  4. <template id="tpl">
  5. <div>
  6. <input type="text" v-model="inputData" readonly="readonly">
  7. <p>
  8. <button @click="request('测试地址1:睡眠2秒')">按钮A</button>
  9. <button @click="request('测试地址2:睡眠1秒')">按钮B</button>
  10. </p>
  11. </div>
  12. </template>
  13. <script src="https://unpkg.com/vue/dist/vue.js"></script>
  14. <script type="text/javascript" src="./vue-resource.min.js"></script>
  15. <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>
  16. <script type="text/javascript">
  17. Vue.use(VueResource)
  18. new Vue({
  19. el: '#app',
  20. data: {
  21. q: Queue()
  22. },
  23. components: {
  24. 'my-component': {
  25. template: '#tpl',
  26. data: function () {
  27. return {
  28. inputData: '默认的'
  29. }
  30. },
  31. methods: {
  32. request: function (url) {
  33. this.q.queue('fx', function (next){
  34. this.$http.get(url).then(function(res) {
  35. this.inputData = res.data
  36. next()
  37. })
  38. }.bind(this))
  39. }
  40. },
  41. props: ['q']
  42. },
  43. }
  44. })
  45. </script>

引入了我的queue,在vue实例上,创建一个q属性存储queue对象并传递给子组件。在子组件中,我们每次点击一个按钮,都会将一个ajax请求的函数添加到fx队列中,在jquery中,fx类型的队列存储着动画函数,可以处理异步函数队列的有序执行。不传递这个值会默认fx类型,所以也可以直接在queue方法中传递一个方法就行。

队列的代码如下:

  1. ;function Queue() {
  2.  
  3. // 数据缓存对象
  4. var cache = {};
  5.  
  6. var queueList = {
  7. // type默认是fx,是动画队列
  8. queue: function(type,data) {
  9. var args = arguments;
  10. //没有参数直接返回
  11. if(!args.length){
  12. return;
  13. }
  14.  
  15. var q = null;
  16. // 只有一个参数并且是个函数
  17. if(args.length == && typeof type === 'function') {
  18. data = type;
  19. type = 'fx';
  20. }
  21.  
  22. q = cache[type] || [];
  23.  
  24. // 添加缓存
  25. if( data instanceof Array) {
  26. q = data;
  27. }else {
  28. q.push(data)
  29. }
  30. cache[type] = q;
  31.  
  32. //如果是动画队列并且没有开始的动画,执行第一个动画函数
  33. if(type == 'fx' && q.toString().indexOf('inprogress') === -) {
  34. queueList.dequeue()
  35. }
  36.  
  37. return q;
  38.  
  39. },
  40. dequeue: function(type) {
  41. var fn, queue;
  42. type = type || 'fx';
  43. queue = cache[type];
  44. if(queue.length == ) {
  45. return;
  46. }
  47.  
  48. fn = queue.shift();
  49.  
  50. if( fn === 'inprogress' ) {
  51. fn = queue.shift();
  52. }
  53. if( fn ) {
  54. if(type === 'fx') {
  55. queue.unshift('inprogress');
  56. }
  57. fn.call(null,function() {
  58. queueList.dequeue(type);
  59. })
  60. }
  61. },
  62. // 延迟使用setTimeout来实现
  63. delay: function(type,timeout) {
  64. if(!type) {
  65. return;
  66. }
  67. if(arguments.length == ) {
  68. timeout = type;
  69. type = 'fx';
  70. }
  71.  
  72. if(typeof timeout == 'number') {
  73. var q = cache[type];
  74. if(!q) {
  75. q = cache[type] = [_delay];
  76. }else {
  77. q.push(_delay)
  78. }
  79.  
  80. }
  81. function _delay() {
  82. setTimeout(queueList.dequeue, timeout);
  83. }
  84.  
  85. return this;
  86.  
  87. },
  88. get: function(type) {
  89. type = type || 'fx';
  90. return cache[type];
  91. }
  92. }
  93.  
  94. return queueList;
  95. }

这个就不解释了,比起jquery源码,这个代码就显得很简单,jquery中做了大量的处理,然而博主并没有那么厉害,只能简单的写了这点。有js基础的应该看得懂,如果想学jq源码,推荐 艾伦 Aaron 的博客园

感谢阅读

一篇知乎的故事 - javascript技术贴的更多相关文章

  1. FineUI(专业版)实现百变通知框(无JavaScript代码)!

    博客园已经越来越不公正了,居然说我这篇文章没有实质的内容!! 我其实真的想问哪些通篇几十个字,没任何代码和技术分享,嚷嚷着送书的文章的就能雄霸博客园首页几天,我这篇文章偏偏就为管理员所容不下. 其实我 ...

  2. 能说明你的Javascript技术很烂的五个原因

    Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西 ...

  3. 细数Javascript技术栈中的四种依赖注入

    作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...

  4. 第61节:Java中的DOM和Javascript技术

    Java中的DOM和Javascript技术 DOM是一门技术,是文档对象模型.所需的文档只有标记型文档,如我们所学的html文档(文档中的所有标签都封装成为对象了) DOM: 为Document O ...

  5. 通过 profiling 定位 golang 性能问题 - 内存篇 原创 张威虎 滴滴技术 2019-08-02

    通过 profiling 定位 golang 性能问题 - 内存篇 原创 张威虎 滴滴技术 2019-08-02

  6. 奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

    奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

  7. 2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  8. 【JavaScript】我的JavaScript技术总结第一篇——编程细节

    遍历数组 for (var i=0, l=arr.length; i<l; i++) 这样写的一个好处就是让每次循环少一步获取数组对象长度的操作,数组长度越长,价值越明显. 判断变量的真假 if ...

  9. 一篇JavaScript技术栈带你了解继承和原型链

    作者 | Jeskson 来源 | 达达前端小酒馆 1 在学习JavaScript中,我们知道它是一种灵活的语言,具有面向对象,函数式风格的编程模式,面向对象具有两点要记住,三大特性,六大原则. 那么 ...

随机推荐

  1. jqGrid简述

    转自:http://www.blogjava.net/ilovebabyfat/archive/2012/04/06/373456.html jqGrid学习之 ------------- 安装 1. ...

  2. HTML编辑模式下制作表格

    前面有朋友问如何做图文并茂的音乐帖子,的确音乐能以表格式做出来,更能让人过目不忘,何况帖子制作过程本身就是创作,包含了制作人对音乐的理解和爱好.以下简单介绍用代码HTML制作表格,希望对大家有所帮助. ...

  3. python web开发基本概念

    参考了廖雪峰的Python博客. web请求顺序: 浏览器发送一个http请求 服务器收到请求后,生成一个html文档. 服务器将html文档作为http相应的body发送给浏览器 浏览器收到http ...

  4. iOS开发——单例模式

    一.用if语句实现单例 1.在.h文件中 #import <Foundation/Foundation.h> @interface YYTRequestTool : NSObject +( ...

  5. iOS开发——导入第三方库引起的unknown type name 'NSString'

    今天加入SVProgressHUD的第三方库的时候报了24个错误( too many errors emitted, stopping now),都是 expected identifier or ' ...

  6. iOS开发——生成条形码,二维码

    - (void)viewDidLoad { [super viewDidLoad]; self.imageView.image = [self generateBarCode:@"15248 ...

  7. S3C2440 ADC详解

    S3C2440拥有八通道的十位ADC, 最大转换率为2.5MHz A/D转换器时钟下的500KSPS.A/D转换器支持片上采样-保持功能和掉电模式的操作. 八个通道中有四个通道适用于电阻屏的触摸屏触摸 ...

  8. objective-c之各种数值

    各种数值 NSArray和NSDictionary都只能存储对象,不能存储任何基本类型的数据,如int,float,struct.因此我们可以用对象来封装基本的数值. NSNumber Cocoa提供 ...

  9. 微信小程序之----消息提示框toast

    toast toast为消息提示框,无按钮,如需关闭弹框可以添加事件设置hidden为true,在弹框显示后经过duration指定的时间后触发bindchange绑定的函数. 官方文档 .wxml ...

  10. Sublime Text 快捷键--持续更新

    快捷键 功能 说明 ctrl+D 选取一个单词连续按组合键会选择页面所有相同的这个单词   ctrl+Z 撤销上一个操作   ctrl+Y 恢复上一个操作   ctrl+shift+F 底部打开搜索全 ...