JS中的异步和单线程
异步和单线程
同步和异步的区别?
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对状态的影响
本文为作者原创文章,转载无需和我联系,但请注明转载链接。 【前端黑猫】