咱们来聊聊JS中的异步,以及如何异步,菜鸟版
2016-08-14 00:19
246 查看
为什么需要异步?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无法捕获异步里面的代码。
大前端群: 369451410 欢迎你的加入,一起前端,一起进步。
问题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无法捕获异步里面的代码。
大前端群: 369451410 欢迎你的加入,一起前端,一起进步。
相关文章推荐
- JS中的异步,以及如何异步
- 菜鸟学exchange之二:如何管理邮件用户以及邮件策略的设置
- 表单提交到下一个页面后,再点击IE上的后退,如何能让表单内容再次显示出来?(以及当前页禁止IE返回按钮js)
- js中方法重载如何实现?以及函数的参数问题
- js 异步操作回调函数如何控制执行顺序
- AsyncTask异步任务类以及如何给它传递参数
- 页面前台通过JS访问WEB SERVICES,以及如何处理返回结果.
- js中checkbox长度为undefinde如何解决以及取checkbox有多少被选中
- js中方法重载如何实现?以及函数的参数问题
- js 如何获取class的元素 以及创建方法getElementsByClassName
- yii 链接地址的格式以及如何引用外部js,css,img
- 菜鸟学exchange之二:如何管理邮件用户以及邮件策略的设置
- jsp/js中如何添加调试信息以及如何显示出来
- linux基础之使用异步 I/O 大大提高应用程序的性能 学习何时以及如何使用 POSIX AIO API
- 在js中如何实现方法重载?以及函数的参数问题
- 菜鸟学exchange之二:如何管理邮件用户以及邮件策略的设置
- Cookie操作以及如何在js中调用jsp变量
- 使用异步 I/O 大大提高应用程序的性能 学习何时以及如何使用 POSIX AIO API
- ajax如何经过后台返回json数组以及在在js中得到json对象
- 聊聊性能测试、操作系统优化对性能测试的影响,以及如何优化操作系统