大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态。

一、阻塞示例

        function f1(){
for (var i = ; i < ; i++) {
console.log('f1');
}
}
function f2(){
console.log('f2');
}
f1();
f2();

f1、f2依次执行,控制台打印:

二、setTimeout函数

        function f1(){
for (var i = ; i < ; i++) {
setTimeout(()=>{
console.log('f1');
},);
}
}
function f2(){
console.log('f2');
}
f1();
f2();

f1、f2依次执行,控制台打印:

看上去好像先执行了f2,后续才执行了f1,其实不然,实际上依旧是先执行f1,再执行f2,没有实现异步,f1、f2依然是同步的(不要质疑,我说的是f1,f2没有实现异步)。

首先执行f1,利用for循环开启2000个定时器;

然后执行f2,打印字符串;

时间到了,2000个定时器触发。

注意:定时器到了时间触发之后,也并不是立即执行的,这要取决于js单线程内有没有还有没有函数正在运行,我们来看一个例子:

        function f8(){
for (let i = ; i < ; i++) {
setTimeout(()=>{
console.log('f8'+i);
},);
}
}
function f9(){
for (let j = ; j < ; j++) {
console.log('f9'+j);
}
}
f8();
f9();

我们看到,定时器的时间参数值很小,50ms,依然是依次执行f8、f9;

可以看到,虽然定时器先开启,并且第一个定时器在50ms之后,理当执行,但是此时发现,f9这个函数一直在执行任务,占据了js线程,所以这些定时器任务只好乖乖地等f9的循环走完,才开始执行。

所以说js声明的所有变量/函数都是同步的(ES6的Promise实例化之后可以有一个立即执行代码块,可视为同步任务);

但是我们可以通过各种方式开启一个异步任务(例如setTimeout函数的callback,Promise对象的then(callback)回调);

三、同步队列、异步队列

因为js是单线程的,所以任务会在线程上依次逐个执行;

在主线程上的任务队列,这些任务是同步的,他们会按先后依次执行;

另外还有一种任务队列,暂且称他们为异步任务队列,顾名思义,他们是异步任务,异步任务的特点是,必须等主线程上的任务没有了之后,才依次进入主线程执行。

来个例子感受一下:

ok,根据上图,我们可以知道,上述代码中,任务建立的顺序为:

同步任务:Promise实例化、f1的第一行打印、f1的for循环开启1000个定时器、5个f2的字符串打印;

异步任务:Promise的then回调、1000个定时器回调。

再根据之前的任务执行顺序分析,先不要看下面的执行结果,在心中想一下控制台的打印结果。

关于上述所提到的同步队列和异步队列(只是一种形象的说法),详情请戳下篇博客

四、异步实现

从上面我们可以发现,setTimeout(定时器)的回调是异步任务,这些个任务是直接放到异步任务队列中等待的。

我们熟知的ajax之所以是异步,完全得益于XMLHttpRequest这个异步对象。

ES6为方便异步编程,直接提供了一个异步对象Promise,使得异步编程变得简单。

浅谈js异步的更多相关文章

  1. 浅谈JS异步轮询和单线程机制

    单线程特点执行异步操作 js是单线程语言,浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务就会排队形成一个任务队列排队等候执行.一般而已,相对耗时的操作是要通过异步 ...

  2. 浅谈JS异步(asychrouous)

    一.概念 (1)asychronous 异步 是JS这种单线程语言解决多任务的一种方法,将耗时的任务(io)设定为异步工作,先交给浏览器负责相关功能的线程来实现耗时的部分工作,按顺序放入任务队列中,等 ...

  3. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  4. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  5. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  6. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  7. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  8. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

  9. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

随机推荐

  1. 关于git pull时出现的问题及解决反思

    前因 在前面由于已经git过一次,按照娄老师的要求,代码一个一个commit,所以删掉之前的git仓库(用la查看,使用rm -rf .git删除).但远程origin已经存在,所以执行git rem ...

  2. 20145322 《Java程序设计》第6周学习总结

    20145322 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 10.1.1 串流设计的概念 Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象. ...

  3. # PHP学习笔记之一

    PHP学习笔记之一 标签(空格分隔): PHP 资料来源:慕课网PHP入门篇.PHP学习手册 一.变量 变量定义 $变量名 = 变量值; $var = "xxx"; 变量类型查看 ...

  4. eclipse隐藏关闭的工程

    打开上面这个视图

  5. 01_zookeeper简介(刷新)

    1. 分布式系统及其问题 zookeeper是帮助我们构建分布式系统的一个软件(协调员的角色)首先,我们要明白分布式系统以及它的问题,之后才能理解为什么有zookeeper 1.1 分布式系统 分布式 ...

  6. oracle 顺序号生成函数。仿Sequence

    问题提出自项目中的老代码:一个Bill表,存储所有的表单信息,比如:员工入职单,离职单等等.(别喷,我知道要分多个表.但领导的意愿你是没办法违背的)表单的单据号是以四个字母+年月日+数字顺序号来表示. ...

  7. python:使用Fabric自动化你的任务

    http://www.th7.cn/Program/Python/2012/03/05/62236.shtml

  8. js执行环境的周边概念

    一.熟悉几个名词: 1.执行环境(execution context),也叫执行上下文,每个函数都会有自己的执行环境:当浏览器首次加载脚本时,他将默认进入全局执行环境:如果接下来要调用一个内部函数,则 ...

  9. [sping]xml配置文件中factory-bean与factory-method(spring使用工厂方法注入bean)

    public class CarFactory { //非静态方法 public Car createCar(){ Car car = new Car(); car.setBrand("BM ...

  10. Python面向过程和面向对象基础

    总结一下: 面向过程编程:根据业务逻辑从上到下的写代码-----就是一个project写到底,重复利用性比较差 函数式:将某些特定功能代码封装到函数中------方便日后调用 面向对象:对函数进行分类 ...