一篇知乎的故事 - javascript技术贴
前言
本文的发表源于知乎的一篇文章。文章链接如下:如果你想靠前端技术还房贷,你不能连这个都不会。
前提
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 == && 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') === -) {
- queueList.dequeue()
- }
- return q;
- },
- dequeue: function(type) {
- var fn, queue;
- type = type || 'fx';
- queue = cache[type];
- if(queue.length == ) {
- 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 == ) {
- 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技术贴的更多相关文章
- FineUI(专业版)实现百变通知框(无JavaScript代码)!
博客园已经越来越不公正了,居然说我这篇文章没有实质的内容!! 我其实真的想问哪些通篇几十个字,没任何代码和技术分享,嚷嚷着送书的文章的就能雄霸博客园首页几天,我这篇文章偏偏就为管理员所容不下. 其实我 ...
- 能说明你的Javascript技术很烂的五个原因
Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西 ...
- 细数Javascript技术栈中的四种依赖注入
作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...
- 第61节:Java中的DOM和Javascript技术
Java中的DOM和Javascript技术 DOM是一门技术,是文档对象模型.所需的文档只有标记型文档,如我们所学的html文档(文档中的所有标签都封装成为对象了) DOM: 为Document O ...
- 通过 profiling 定位 golang 性能问题 - 内存篇 原创 张威虎 滴滴技术 2019-08-02
通过 profiling 定位 golang 性能问题 - 内存篇 原创 张威虎 滴滴技术 2019-08-02
- 奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术
奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术
- 2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- 【JavaScript】我的JavaScript技术总结第一篇——编程细节
遍历数组 for (var i=0, l=arr.length; i<l; i++) 这样写的一个好处就是让每次循环少一步获取数组对象长度的操作,数组长度越长,价值越明显. 判断变量的真假 if ...
- 一篇JavaScript技术栈带你了解继承和原型链
作者 | Jeskson 来源 | 达达前端小酒馆 1 在学习JavaScript中,我们知道它是一种灵活的语言,具有面向对象,函数式风格的编程模式,面向对象具有两点要记住,三大特性,六大原则. 那么 ...
随机推荐
- jqGrid简述
转自:http://www.blogjava.net/ilovebabyfat/archive/2012/04/06/373456.html jqGrid学习之 ------------- 安装 1. ...
- HTML编辑模式下制作表格
前面有朋友问如何做图文并茂的音乐帖子,的确音乐能以表格式做出来,更能让人过目不忘,何况帖子制作过程本身就是创作,包含了制作人对音乐的理解和爱好.以下简单介绍用代码HTML制作表格,希望对大家有所帮助. ...
- python web开发基本概念
参考了廖雪峰的Python博客. web请求顺序: 浏览器发送一个http请求 服务器收到请求后,生成一个html文档. 服务器将html文档作为http相应的body发送给浏览器 浏览器收到http ...
- iOS开发——单例模式
一.用if语句实现单例 1.在.h文件中 #import <Foundation/Foundation.h> @interface YYTRequestTool : NSObject +( ...
- iOS开发——导入第三方库引起的unknown type name 'NSString'
今天加入SVProgressHUD的第三方库的时候报了24个错误( too many errors emitted, stopping now),都是 expected identifier or ' ...
- iOS开发——生成条形码,二维码
- (void)viewDidLoad { [super viewDidLoad]; self.imageView.image = [self generateBarCode:@"15248 ...
- S3C2440 ADC详解
S3C2440拥有八通道的十位ADC, 最大转换率为2.5MHz A/D转换器时钟下的500KSPS.A/D转换器支持片上采样-保持功能和掉电模式的操作. 八个通道中有四个通道适用于电阻屏的触摸屏触摸 ...
- objective-c之各种数值
各种数值 NSArray和NSDictionary都只能存储对象,不能存储任何基本类型的数据,如int,float,struct.因此我们可以用对象来封装基本的数值. NSNumber Cocoa提供 ...
- 微信小程序之----消息提示框toast
toast toast为消息提示框,无按钮,如需关闭弹框可以添加事件设置hidden为true,在弹框显示后经过duration指定的时间后触发bindchange绑定的函数. 官方文档 .wxml ...
- Sublime Text 快捷键--持续更新
快捷键 功能 说明 ctrl+D 选取一个单词连续按组合键会选择页面所有相同的这个单词 ctrl+Z 撤销上一个操作 ctrl+Y 恢复上一个操作 ctrl+shift+F 底部打开搜索全 ...