JavaScript是一门单线程语言,一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
如果一个任务一直在运行,那么后面的任务就需要一直等待,拖延整个程序,可能会造成浏览器无反应,无法继续执行。为了解决这样的问题,js的执行模式分为两种:同步和异步。
同步:停止等待运行结束,继续后续的运行
异步:就是需要等待一个内容完成后继续执行后面的内容,但是不能将后面的内
容写在等待函数外,否则就会同时执行两个
其实同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
具体来说,异步运行机制如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了
运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",
看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
JavaScript中最简单的异步就是setTimeout和setInterval函数,另外还有两个,分别是load事件和requestAnimationFrame()跳动的帧数。
console.log( "a" );
setTimeout(function() {
console.log( "b" )
}, 2000 );
setTimeout(function() {
console.log( "c" )
}, 1000 );
setTimeout(function() {
console.log( "d" )
}, 500 );
console.log( "e" );
// body部分
<img src="./img/16-.jpg" id="img1">
<img src="./img/17.jpg" id="img2">
// js部分
window.onload = function () {
// 当窗口内的内容全部加载完成
var img1 = document.querySelector("#img1");
var img2 = document.querySelector("#img2");
console.log(img1.offsetWidth, img2.offsetWidth)
}
也可以看下面的这个,获取两个图片的宽度,首先是sum=0;给图片做加载侦听事件,先获取到第一张图片并且获取到宽度,之后加在用同一个方法对第二张图片进行load加载事件,最后输出。这种方法比较麻烦,若要获取许多,不能一个一个写。所有有了下面的方法:
var sum=0;
var img=new Image();
img.src="./img/16-.jpg";
img.addEventListener("load",loadHandler);
function loadHandler(e){
sum+=img.width;
var img1=new Image();
img1.src = "./img/17.jpg";
img1.addEventListener("load",loadHandler1)
}
function loadHandler1(e) {
sum += this.width;
console.log(sum);
}
使用map方法,将每一个图片都添加load事件,并且执行同一个函数loadHandler,当都加载完成以后,使用map.set()方法,获取到每个图片的属性。最终通过for…of获取到图片的value值,也就是宽度,并将宽度相加,输出总长度。
var map = new Map();
var img1 = new Image();
img1.src = "./img/16-.jpg";
img1.addEventListener("load", loadHandler);
var img2 = new Image();
img2.src = "./img/17.jpg";
img2.addEventListener("load", loadHandler);
function loadHandler(e) {
map.set(this, this.width);
console.log(this,this.width);
if (map.size === 2) {
var sum = 0;
for (var value of map.values()) {
sum += value;
}
console.log(sum);
}
}
3异步操作 —— requestAnimationFrame() 屏幕刷新频率
这里介绍一下它两个优势:
这就是自我认识的同步异步的区别,如果哪里不对,不完善的地方,请帮我指出来,谢谢每个阅读的小伙伴。