异步面试知识点

应用场景

  • 网络请求,如ajax,图片加载
  • 定时任务,如setTimeout

Promise解决callback hell

function loadImg(src) {
    const p = new Promise(
        (resolve, reject) => {
            const img = document.createElement('img')
            img.onload = () => {
                resolve(img)
            }
            img.onerror = () => {
                const err = new Error(`图片加载失败 ${src}`)
                reject(err)
            }
            img.src = src
        }
    )
    return p
}

// loadImg(url).then(img => {
//     console.log(img.width)
//     return img
// }).then(img => {
//     console.log(img.height)
// }).catch(ex => console.error(ex))

const url1 = 'https://img.mukewang.com/5a9fc8070001a82402060220-140-140.jpg'
const url2 = 'https://img3.mukewang.com/5a9fc8070001a82402060220-100-100.jpg'

loadImg(url1).then(img1 => {
    console.log(img1.width)
    return img1 // 普通对象
}).then(img1 => {
    console.log(img1.height)
    return loadImg(url2) // promise 实例
}).then(img2 => {
    console.log(img2.width)
    return img2
}).then(img2 => {
    console.log(img2.height)
}).catch(ex => console.error(ex))

1. Promise三种状态

  • pending resolved rejected

  • pending——> resolved 或 pending——> rejected

  • 变化不可逆

2. Promise状态的表现

  • pending状态,不会触发then和catch

  • resolved状态,会触发后续的then回调函数

  • rejected状态,会触发后续的catch回调函数

3. then和catch改变状态

  • then正常返回resolved,里面有报错则返回rejected

  • catch正常返回resolved,里面有报错则返回rejected

场景题 - promise then和catch的连接



event loop(时间循环、事件轮询)

  1. 同步代码,一行一行放在 Call Stack执行

  2. 遇到异步,会先“记录”,等待时机(定时、网络请求等)

  3. 时机到了,就移动到Callback Queue

  4. 如 Call Stack 为空(即同步代码执行完)Event Loop开始工作

  5. 轮询查找Callback Queue,如有则移动到Call Stack执行

  6. 然后继续轮询查找(永动机一样)



async/await和Promise的关系

async/await是语法糖,本质还是回调函数

  • 执行async函数,返回的是Promise对象

  • await相当于Promise的then(await后面的代码相当于执行异步回调)

  • try...catch可捕获异常,代替了Promise的catch

for - of的 应用场景: 实现异步遍历

宏任务 macroTask 和微任务 microTask

  • 宏任务: setTimeout,setInterval,Ajax,DOM事件
  • 微任务: Promise async/await
    微任务执行时机比宏任务早

1. event-loop和DOM渲染的关系

Call Stack空闲时,就会尝试DOM渲染,然后触发event loop,再执行Callback Queue里的代码,再尝试DOM渲染,如此循环

2. 微任务和宏任务的区别

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

3. 微任务和宏任务的根本区别

  • 宏任务是由浏览器规定的,微任务是由ES6语法规定的
  • 执行顺序:
    1. 同步代码执行完
    2. 执行当前的微任务(微任务不放在Web APIs里,放在micro task queue里)
    3. 尝试DOM渲染
    4. 触发event loop

你可能感兴趣的:(异步面试知识点)