今天在写轮播图防止重复时遇到一个问题。我创建一个变量用于防止重复点击,但是按照我的逻辑加上后没有效果,可以看看我的代码。
var lock = false;$(‘.arrow‘).on(‘click‘,function(e){ if (!lock){ return; } lock = true; e.preventDefault(); if ($(this).hasClass(‘next‘)) { //playNext函数是一个包括了动画的函数 playNext(); }else if ($(this).hasClass(‘pre‘)) { playPrev(); } lock = false })
按照我的逻辑是当点击翻页按钮时就上锁,然后等到翻页函数执行完成之后就把锁打开,就完成了上锁的功能。但是我犯了一个很严重的错误。忽略了动画是异步执行的。代码并不会按照我写得顺序来执行。都说异步、this、和原型链是js学习中的三座大山。今天我就来彻底解决这座山。
一、最明显的异步setTimeout
在js编码中经常会使用到setTimeout,但是很多人会误解setTimeout是js的功能,其实并不,setTimeout是浏览器提供的一个api。比如说最常见的一个例子
console.log(1); setTimeout(function(){ console.log(2) },0) console.log(3);
这段代码的执行结果是1、3、2。可以发现虽然setTimeout的延迟时间是0,也需要等到后面的代码执行完成之后才执行。就是setTimeout的执行原理所导致的。当js按顺序执行时遇到setTimeout时就会将它单独拿出来放在回调队列中,等到其他代码执行完毕之后再去看到没到延迟的时间,如果到了就执行。除了setTimeout是异步之外你还能想到js中哪些是异步的吗?
你仔细想想就会发现js中到处都是异步,下面来看看这个jquery代码示例
$(‘#button‘).on(‘click‘,function(){ console.log(‘你点了‘) $.get(‘/data‘,function(response){ console.log(response) }) console.log(‘数据拿没拿我不知道‘) }) console.log(‘我不在乎你点不点‘)
可以发现执行结果顺序是
- 我不在乎你点不点
- 你点了
- 数据拿没拿我不知道
- response数据
可以发现事件绑定是异步的、ajax请求是异步的(当然ajax也可以设置为同步的,但是ajax如果不是异步还有什么意义,黑人问号),除此之外jq中的动画也是异步。所以说js中处处都是异步
二、异步是一种模式
看了这么多例子那我们该解释一下什么是异步了。异步并不是js独有也不是编程语言独有,它只是一种模式。它跟编程无关,因为你在现实生活中也经常有异步的例子。
比如说:
- 托人买票(买到票之后回电话 :call me back)
- 进站找不到票,排在后面的人不会等前面的人找到再进站。
这时候你可能会思路一个问题,都说js引擎是单线程的,那是怎么样做到异步的呢?其实js的异步都是由‘别人‘完成的,而这个‘别人‘是谁呢?等你自己去发现吧。
现在你明白异步是什么了吗?
总结起来异步就是不等到结果就去做其他的事情,而同步就是耐心等结果再执行。
但是需要注意的是js里的异步它是有返回结果的,只是返回的并不是我们需要的结果,比如说:
- setTimeout的结果是一个id
- $.get的结果是一个请求对象
- addEventListener 的结果是空
希望我们能一起翻越这种大山。