JS基础知识(四)异步和单线程

异步和单线程

问题:

  1. 同步和异步的区别是什么?分别举一个同步和异步的例子

  2. 一个关于setTimeout的笔试题

    	console.log(1)
    	setTimeout(function() {
    		console.log(2)
    	},0)
    	console.log(3)
    	setTimeout(function() {
    		console.log(4)
    	},1000)
    	console.log(5)
  3. 前端使用异步的场景有哪些

知识点:

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执行多次,事件绑定的特点可以多次执行,执行机制与其他相同。

 

解答:

  1. 同步和异步的区别是什么?分别举一个同步和异步的例子
    同步会阻塞,异步不会阻塞,同步alert,异步setTimeout

  2. 一个关于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.

  3. 前端使用异步的场景有哪些
    1.定时任务:setTimeout, setInterval
    2.网络请求:ajax请求,动态<img>加载
    3.事件绑定

猜你喜欢

转载自blog.csdn.net/qq_37021554/article/details/84701036