JavaScript高级部分——第四天

一、懒加载

网页在加载图片的时候,不会一次性全部加载完毕,哪些图片在屏幕的可视区域里面才去加载它

作用

        DOM优化

        节省加载性能

核心思路

        获取屏幕的可视区域的高度:window.innerHeight

        获取的是图片距离浏览器顶部的距离:getBoundingClientRect().top

        然后使用屏幕的可视区域的高度和图片距离顶部的距离进行对比

function lzyLoad(){
    // 注意点:把获取元素放在滚动事件的里面的是为了每次重新获取元素的,
    //如果被删除类名的,那么这个元素就获取不到,也就是说这个图片已经加载过了
    let lzy_image = document.querySelectorAll('.lzy-image')
    // 注意点:当浏览器的可视区域的高度大于等于每一个元素的距离浏览器顶部的距离的时候,
    //那么说明这个元素已经进入可视区域了
    // 遍历做比较
    for(let i=0; i<lzy_image.length; i++){
        if(window.innerHeight>=lzy_image[i].getBoundingClientRect().top+80){
            lzy_image[i].src = lzy_image[i].dataset.src
            // 注意点:删除类名的作用是为了让它不重复去加载(不断的替换src路径)
            lzy_image[i].classList.remove('lzy-image')
        }   
    }
}
lzyLoad()
window.addEventListener('scroll', lzyLoad)

二、js事件轮询机制

javascript 主线程从“任务队列”中读取异步任务回调函数,放到执行栈中依次执行 。这个过程是循环不断的,所以整个的这种运行机制又称为EventLoop(事件循环)。

首先我们要搞懂几个名词

1.js单线程:JavaScript是单线程指的是同一时间只能干一件事情,只有前面的事情执行完,才能执行后面的事情。导致遇到耗时的任务时后面的代码无法执行。

2.同步任务:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的

3.异步任务:多任务多线程,比如:做一件事的同时,可以去做其他事情,当异步任务执行完成之后,会通知javascript主线程执行异步任务的回调函数

异步任务又分为宏任务和微任务

常见的宏任务有:Script整体代码、setTimeout()、setInterval()、I/O、文件操作

常见的微任务:Promise.then()、.catch、和.finally、process.nextTick

每个宏任务执行完后,都会检查是否存在待执行的微任务
如果有,则会将所有待执行的微任务执行完,再执行下一个宏任务
宏任务和微任务是交替执行的

4.调用栈(call stack):又叫执行栈/执行上下文栈,特点是后进先出

5.任务队列(task queue):特点是先进先出

js事件轮询机制大致是这样的:在执行js代码的时候,首先会将Script整体代码放入到调用栈里面,而后从上到下的按顺序执行,若是同步任务就直接执行,若是遇到异步任务就将异步任务转交给WEB API,如此直到Script整体代码执行完毕时,WEB API会将相应的任务分配到宏任务和微任务队列,而后,由于Script整体代码是属于宏任务的范畴,所以js此时会先执行微任务,js会将微任务队列里面的任务依次放入主线程中执行,直到微任务队列空了,再去执行宏任务队列里面的任务,如此往复,直到所有任务都执行完毕

给大家举个例子:

以上这段代码的执行顺序如下:

console.log(1),为同步所以直接执行输出1 

setTimeout(()=>{ console.log(2)},0)为异步代码,转交给WEB API,我们记为 console.log(2)=>0s

new Promise(resolve=>{ console.log(3) resolve()} .then(()=>{ console.log(4) })前半部分为同步任务,直接执行输出3,后半部分为异步任务,转交给WEB API,记为 console.log(4)=>then

中间部分的setTimeout()全为异步,转交给WEB API,记为 setTimeout() => 500ms

new Promise(resolve => console.log(9)resolve()}).then(() => console.log(10) setTimeout(() => console.log(11),0)前半部分为同步代码,直接执行输出9,后半部分为异步代码,转交给WEB API,记为 console.log(10) setTimeout() => then

console.log(12)为同步任务,直接执行输出12,到此时,Script整体代码已经全部执行完毕,该WEB API来分配宏任务和微任务了。此时WEB API里面的东西按照顺序来是:

        console.log(2)=>0s

        console.log(4)=>then

        setTimeout() => 500ms

        console.log(10) setTimeout() => then

WEB API首先将 console.log(4)=>then 和 console.log(10) setTimeout() => then 放进微任务队列中,由于前面执行的Script整体已经是宏任务了,所以会先执行微任务,那么会按照顺序先执行console.log(4),输出4再执行 console.log(10) setTimeout(),前半部分是同步任务之间执行,输出10后半部分为异步任务,转交给WEB API,记为 console.log(11) => 0s

微任务队列执行完毕,WEB API又会分配宏任务,此时WEB API里面的任务按顺序如下:

        console.log(2)=>0s

        setTimeout() => 500ms

        console.log(11) => 0s

由于第二个有延迟500ms,所以先将 console.log(2) console.log(11)放入宏任务队列中,并按顺序执行,先执行console.log(2)输出2,再执行console.log(11)输出11然后再执行 setTimeout() => 500ms,其中的 console.log(5)为同步任务直接执行输出5,其中Promise()前半部分的console.log(6)为同步任务之间执行输出6,Promise()前半部分的 setTimeout()为异步任务,转交给WEB API,记为 console.log(7) =>0s,Promise()的后半部分为微任务,转交给WEB API ,记为 console.log(8) =>then

此时,宏任务队列执行完毕,由WEB API 分配任务,此时WEB API 里面的任务按顺序是:

        console.log(7) =>0s

        console.log(8) =>then

WEB API会将console.log(8) =>then放入到微任务队列,并由js执行,输出8,此时微任务队列已经执行完毕

WEB API会把console.log(7) =>0s放入到宏任务队列,并由js执行,输出7,到此所有的代码都执行完毕,最终的结果为:1 3 9 12 4 10 2 11 5 6 8 7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值