深入理解异步

Posted 罗Q

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解异步相关的知识,希望对你有一定的参考价值。

    

  今天在写轮播图防止重复时遇到一个问题。我创建一个变量用于防止重复点击,但是按照我的逻辑加上后没有效果,可以看看我的代码。

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(‘我不在乎你点不点‘)

可以发现执行结果顺序是

  1. 我不在乎你点不点
  2. 你点了
  3. 数据拿没拿我不知道
  4. response数据

可以发现事件绑定是异步的、ajax请求是异步的(当然ajax也可以设置为同步的,但是ajax如果不是异步还有什么意义,黑人问号),除此之外jq中的动画也是异步。所以说js中处处都是异步

 

二、异步是一种模式

看了这么多例子那我们该解释一下什么是异步了。异步并不是js独有也不是编程语言独有,它只是一种模式。它跟编程无关,因为你在现实生活中也经常有异步的例子。

比如说:

  1. 托人买票(买到票之后回电话 :call me back)
  2. 进站找不到票,排在后面的人不会等前面的人找到再进站。

这时候你可能会思路一个问题,都说js引擎是单线程的,那是怎么样做到异步的呢?其实js的异步都是由‘别人‘完成的,而这个‘别人‘是谁呢?等你自己去发现吧。

现在你明白异步是什么了吗?

总结起来异步就是不等到结果就去做其他的事情,而同步就是耐心等结果再执行。

但是需要注意的是js里的异步它是有返回结果的,只是返回的并不是我们需要的结果,比如说:

  1. setTimeout的结果是一个id
  2. $.get的结果是一个请求对象
  3. addEventListener 的结果是空

希望我们能一起翻越这种大山。

以上是关于深入理解异步的主要内容,如果未能解决你的问题,请参考以下文章

深扒深入理解 JavaScript 中的异步编程

深扒深入理解 JavaScript 中的异步编程

深入理解nodejs中的异步编程

深入理解ajax同步和异步的区别

《深入理解ES6》笔记—— Promise与异步编程

深入理解DOM节点类型第四篇——文档片段节点DocumentFragment