首页

JS中的异步和单线程

kkcode
2023-06-30  阅读 299

异步和单线程

同步和异步的区别?

JS是单线程语言,只能同时做一件事。异步不会阻塞代码的运行,同步会阻塞代码的运行。


浏览器和nodejs已支持JS启动进程,如Web Worker
JS和DOM渲染共用同一个线程,因为JS可修改DOM结构
遇到等待(网络请求,定时任务)不能卡住,所以需要异步 异步通过callback形式调用

手写Promise加载一张图片?

function loadImg(src){
    return new Promise((resolve, reject)=>{
        const img = document.createElement('img)
        img.onload = ()=>{
            resolve(img)
        }

        img.onerror = ()=>{
            reject(new Error(`图片加载失败 ${src}`))
        }

        img.src = src
    })
}

// 使用
loadImg(imgUrl1).then(img1=>{
    console.log(img1.width);
    rerurn img1
}).then(img1=>{
    console.log(img1.height);
    return loadImg(imgUrl2);
}).then(img2=>{
    console.log(img2.width);
    return img2
}).then(img2=>{
    console.log(img2.height);
}).catch(err=>{
    console.error(err);
})复制代码
  • 前端使用异步的场景有哪些(网络请求: 如ajax图片加载;定时任务:如setTimeout)

Promise解决了什么问题?(回调地狱 callback hell)

考点:JS异步

请描述event loop (事件循环/事件轮询)的机制,可画图。

异步是基于回调来实现。 event loop 是异步回调的实现原理。

// JS 如何执行

- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步。

console.log(1);

setTimeout(()=>{
    console.log(2);
},1000)

console.log(3);


总结:
- 同步代码,一行一行放在 Call Stack 中执行
- 遇到异步,会先"记录"下,等待时机(定时,网络请求等)
- 时机到了,就移到callback queue中
-Call Stack 为空(同步代码执行完),当Call Stack空闲,执行当前的微任务(micro task queue),会尝试DOM渲染,Event Loop 开始工作
- 轮询查找 Callback Queue , 如有则移到到 Call Stack 中执行
- 然后继续轮询查找(永动机一样)复制代码

什么是宏任务和微任务,两者有什么区别?

宏任务:setTimeout, setInterval, Ajax, DOM事件 微任务:Promise async/await

微任务执行时机比宏任务要早。

  • event-loop 和DOM渲染的关系 JS是单线程的,而且和DOM渲染共用一个线程 JS执行的时候,得留出一些时机供DOM渲染

微任务:DOM渲染前触发,如Promise 宏任务:DOM渲染后触发,如setTimeout

Promise有哪些状态,如何变化?

  • 三种状态(pending,resolved,rejected)
  • 状态的表现和变化(pending=>resolved或pending=>rejected,状态一旦发生变化,不可逆)
  • then和catch对状态的影响
本文为作者原创文章,转载无需和我联系,但请注明转载链接。 【前端黑猫】