异步和单线程
问题:
-
同步和异步的区别是什么?分别举一个同步和异步的例子
-
一个关于setTimeout的笔试题
console.log(1) setTimeout(function() { console.log(2) },0) console.log(3) setTimeout(function() { console.log(4) },1000) console.log(5)
- 前端使用异步的场景有哪些
知识点:
JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。
JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。
---摘自阮一峰es6入门
1.什么是异步(对比同步)
同步任务:主线程排队执行的任务,前一个执行完毕,后一个才能执行。
异步任务:不进入主线程,而进入任务队列的任务,只有等主线程的任务结束以后,任务队列开始通知主线程,请求执行任务,该任务才能进入主线程进行执行。
主要区别:阻塞
同步会阻塞后面的代码的执行,而异步不会,异步就自己管自己的。
//异步
console.log(100)
setTimeout(function() {
console.log(200)
}, 1000)
console.log(300)
//100 300 200
//对比同步的过程
console.log(100)
alert(200)
console.log(300)
//100 200 300
什么时候需要异步呢?
1.可能会发生等待的时候
2.等待的过程中不会像alert一样阻塞程序运行
3.等待的状态都需要异步。
2.前端使用异步的场景
1.定时任务:setTimeout,setTimeInterval
2.网络请求:ajax请求,动态<img>加载
3. 事件绑定
//ajax
console.log('start')
$.get('./test-test.json', function (data) {
console.log(data)
})
console.log('end')
//start end data内容
//动态图片加载
console.log('start')
var img = document.createElement('img')
img.onload = function () {
console.log('loaded')
}
img.src= 'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=300969297,3492652524&fm=58'
console.log('end')
//start end loaded
//事件绑定
console.log('start')
var btn1 = document.getElementById('btn1')
btn1.addEventListener('click', function() {
console.log('click')
})
console.log('end')
//start end click
3.异步和单线程
异步:异步场景会被拿出去,放在一边。当程序都执行完了,再看异步场景是否能执行了。
单线程:一次只能执行一个,一个个轮流下来。
//异步
console.log(100)
setTimeout(function() {
console.log(200)
}, 1000)
console.log(300)
//100 300 200
过程:
1.先执行第一行,打印100,
2.再执行setTimeout后,传入setTimeout的函数会被暂存起来,不会立即执行(单线程的特点,不能同时干两件事)
3.执行最后一行,打印300
4.待所有程序执行完后,处于空闲状态,会立马看有没有暂存起来的要执行的。
5.发现暂存起来的setTimeout中的函数无需等待时间,就立即来执行。
//对比同步的过程
console.log(100)
alert(200)
console.log(300)
//100 200 300
过程:
1.先执行第一行,打印100
2.再遇到alert弹窗,阻塞,当点击完以后进行一步
3.打印300
//ajax
console.log('start')
$.get('./test-test.json', function (data) {
console.log(data)
})
console.log('end')
//start end data内容
1.打印start
2.发送请求,等待,暂存函数,类似把他封印起来,
3.打印end
4.执行完了看看有没有什么是在等待的,解封的时候就是看他什么时候有返回。
//事件绑定
console.log('start')
var btn1 = document.getElementById('btn1')
btn1.addEventListener('click', function() {
console.log('click')
})
console.log('end')
//start end click
1.打印start
2.绑定事件,暂存异步的函数,把他封印起来
3.打印end
4.当点击的时候会解封,然后执行打印click
onclick执行多次,事件绑定的特点可以多次执行,执行机制与其他相同。
解答:
-
同步和异步的区别是什么?分别举一个同步和异步的例子
同步会阻塞,异步不会阻塞,同步alert,异步setTimeout -
一个关于setTimeout的笔试题
写出结果:console.log(1) setTimeout(function() { console.log(2) },0) console.log(3) setTimeout(function() { console.log(4) },1000) console.log(5)
// 1 3 5 2 4
for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); }
结果:五个5
因为for的同步优于setTimeout异步,然后结果就是for执行完了以后,五个setTimeout在等待着,然后同时输出五个i,因为i是var是全局作用域,此时的i已经变成了5.所以输出的都是5. - 前端使用异步的场景有哪些
1.定时任务:setTimeout, setInterval
2.网络请求:ajax请求,动态<img>加载
3.事件绑定