再谈Javascript中的异步以及如何异步


Posted in Javascript onAugust 19, 2016

为什么需要异步?why?来看一段代码。

问题1:

for(var i=0;i<100000;i++){

}

alert('hello world!!!');

这段代码的意思是执行100...次后再执行alert,这样带来的问题是,严重堵塞了后面代码的执行,至于为什么,主要是因为JS是单线程的。

问题2:

我们通常要解决这样一个问题,如果我们需要在head里面加入script代码的话,一般会将代码写在window.onload里面(如果操作了dom的话),你有没有想过,为什么要加window.onload?原因就是你在操作dom的时候script后面的html代码浏览器还没有开始加载,结果人家还没有出生你就想着去娶她,这可能吗?当然不可能,加上window。onload之所以可以是因为,window.onload里面的代码是在文档全部加载完毕后执行的,也就相当于异步。

问题3:

有时候页面并不需要一次性把所有的代码都加载,更多的时候我们是按照某个需求才去加载某段代码的。 

什么是单线程?

你可以这样理解单线程就是代码一段一段的执行,先执行前面的,前面的执行完了再执行后面的。 

那JS中有哪些是异步的呢?

我相信这个东西,几乎都用烂了,它就是setTimeout/setInterval当然还有Ajax,Ajax异步我相信大家都知道,当然也可以同步但没人那么去做,但是对于setTimeout和setInterval是异步可能有些小伙伴不同了解,下面说说为什么说setTimeout是异步的。

setTimeout(function(){
console.log(0);
},0)

console.log(1);

// 1

// 0

运行这段代码后先打印的是1,而不是0,有些小伙伴是不是开始迷惑了,这里我们虽然给setTimeout设置的是0秒后执行console.log(0)  ,但是这个setTimeout很特别,因为它是异步的,我们先抛开这里为什么打印的是1然后才是0,先来聊聊什么是异步。 

什么是异步?

比方说有些饭店你去吃饭需要提前预定,等其他人吃完你才能去,因此在其他人吃饭的时候你可以去干其他的事情,等其他人吃完了会有人来通知你,于是你可以去了,那么对于代码来说,如ajax,你定义了一个回调方法,这个回调方法并不会当时就去执行,而是等待服务器响应完成之后才会去执行这段代码。 

我们回到前面那段setTimeout身上,它的工作原理是这样的,当你定义setTimeout那一刻起(不管时间是不是0),js并不会直接去执行这段代码,而是把它扔到一个事件队列里面,当页面中所有同步任务都干完了以后,才会去执行事件队列里面的代码。什么是同步,除了异步代码就是同步—_—。 

JS怎么实现异步?

1.利用setTimout实现异步

setTimeout(function(){
console.log(document.getElementByTagName('body')[0]);
},0)

但是setTimeout有些小小的问题,就是时间不精确,如果你想更快的执行这段代码我们可以使用html5提供的一个函数。

requestAnimationFrame(function(){
console.log(document.getElementByTagName('body')[0]);
})

requestAnimationFrame和setTimeout的区别就在于requestAnimationFrame比setTimeout更快执行,因此很多人用requestAnimationFrame来制作动画。

2.动态创建script标签

var head = document.getElementByTagName('head')[0];
var script = document.createElement('script');
script.src = '追梦子.js';
head.appendChild('script');

   3.利用script提供的defer/async

<script src="xx.js" defer></script>

defer:当页面加载完毕以后才去执行这段代码。

<script src="xx.js" async></script>

async:异步执行script代码

不过异步也是缺点的,比如下面这段代码:

  正常代码: 

 

try{
throw new Error('hello world');
}catch(err){

console.log(err);
}

// Error: hello world(…)

  异步代码:  

try{
setTimout(function(){


throw new Error('hello world');

},0)
}catch(err){

console.log(err);
}

// ReferenceError: setTimout is not defined(…)

可以发现catch里面的代码并没有执行,也就是说try无法捕获异步里面的代码。

总结

关于JS中的异步以及如何异步到这就基本结束,关于JS的异步算是老生常谈了,但是还是希望本文的内容对大家能有一些帮助。

Javascript 相关文章推荐
复制本贴标题和地址的js代码
Jul 01 Javascript
JavaScript入门教程(10) 认识其他对象
Jan 31 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
Apr 25 Javascript
jquery获得option的值和对option进行操作
Dec 13 Javascript
Python脚本后台运行的几种方式
Mar 09 Javascript
浅谈移动端之js touch事件 手势滑动事件
Nov 07 Javascript
CSS+jQuery实现简单的折叠菜单
Dec 20 Javascript
AngularJs 常用的过滤器
May 15 Javascript
jQuery实现下拉菜单的实例代码
Jun 19 jQuery
浅谈layui使用模板引擎动态渲染元素要注意的问题
Sep 14 Javascript
vue实现设置载入动画和初始化页面动画效果
Oct 28 Javascript
extjs图表绘制之条形图实现方法分析
Mar 06 Javascript
用原生js统计文本行数的简单示例
Aug 19 #Javascript
jQuery购物网页经典制作案例
Aug 19 #Javascript
手机Web APP如何实现分享多平台功能
Aug 19 #Javascript
浅谈Javascript中的12种DOM节点类型
Aug 19 #Javascript
js实现select选择框效果及美化
Aug 19 #Javascript
JavaScript面向对象编写购物车功能
Aug 19 #Javascript
javascript设计模式之module(模块)模式
Aug 19 #Javascript
You might like
PHP实现算式验证码和汉字验证码实例
2015/03/09 PHP
PHP常用的排序和查找算法
2015/08/06 PHP
PHP实现自动识别原编码并对字符串进行编码转换的方法
2016/07/13 PHP
php解决DOM乱码的方法示例代码
2016/11/20 PHP
PHP基于Redis消息队列实现发布微博的方法
2017/05/03 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
浅析javascript闭包 实例分析
2010/12/25 Javascript
用Jquery选择器计算table中的某一列某一行的合计
2014/08/13 Javascript
javascript学习笔记(三)BOM和DOM详解
2014/09/30 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
Node.js实用代码段之正确拼接Buffer
2016/03/17 Javascript
easyUI实现类似搜索框关键词自动提示功能示例代码
2016/12/27 Javascript
JavaScript实现form表单的多文件上传
2020/03/27 Javascript
axios如何利用promise无痛刷新token的实现方法
2019/08/27 Javascript
Python中的类学习笔记
2014/09/23 Python
Python中使用SAX解析xml实例
2014/11/21 Python
python实现给数组按片赋值的方法
2015/07/28 Python
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
mac系统安装Python3初体验
2018/01/02 Python
TensorFlow实现MLP多层感知机模型
2018/03/09 Python
PyQt5每天必学之关闭窗口
2018/04/19 Python
python 实现判断ip连通性的方法总结
2018/04/22 Python
使用Python OpenCV为CNN增加图像样本的实现
2019/06/10 Python
Python基于Tensor FLow的图像处理操作详解
2020/01/15 Python
python实现IOU计算案例
2020/04/12 Python
HTML5地理定位_动力节点Java学院整理
2017/07/12 HTML / CSS
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
C#面试问题
2016/07/29 面试题
客服端调用EJB对象的几个基本步骤
2012/01/15 面试题
自主招生自荐信格式
2013/12/03 职场文书
护士自我鉴定总结
2014/03/24 职场文书
梅花魂教学反思
2014/04/25 职场文书
低碳环保口号
2014/06/12 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
MySQL InnoDB ReplicaSet(副本集)简单介绍
2021/04/24 MySQL
Python使用DFA算法过滤内容敏感词
2022/04/22 Python