面试题记录(任务队列&Promise)

280 阅读2分钟

微任务宏任务

参考地址

  • 将js执行分为 主线程,宏任务,微任务。 三种
  • 执行的先后顺序是 主线程 —— 微任务 —— 宏任务
  • 微任务包括:Promise,async await,MutaionObserver、process.nextTick(Node.js)
  • 宏任务包括:setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js)
  • js执行先进先出的原则

第一题

async function async1() {
    console.log('async1 start'); 
    await async2();
    console.log('async1 end'); 
}
async function async2() {
    console.log('async2'); 
}
console.log('script start'); 
setTimeout(function() {
    console.log('setTimeout'); 
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1'); 
    resolve();
}).then(function() {
    console.log('promise2'); 
});
console.log('script end');

/**
    script start
    async1 start
    async2
    promise1
    script end
    async1 end
    promise2
    setTimeout
*/

分析:

  • 同步的主线程任务先执行
  • new Promise的时候,定义时候要执行
  • await 语句先执行,然后将 await后的语句放入任务队列中
  • setTimeout宏任务最最后执行

第二题

new Promise((res,rej)=>{
    console.log('promise')
    res()
}).then(()=>{
    console.log('then');
    return new Promise((res2,rej2)=>{
        console.log('promise2')
        res2()
    }).then(()=>{
         console.log('then2')
    })
}).then(()=>{
     console.log('thenA')   
}).finally(()=>{
    console.log('finally')
}).then(()=>{
    console.log('thenB')
})

setTimeout(()=>{
   console.log('timeout')
},0)

/** 
    输出结果如下:
    promise
    then
    promise2
    then2
    thenA
    finally
    thenB
    timeout
*/
  • then 里如果还有异步微任务,宏任务的执行依旧是等微任务结束后输出,所以timeout最最最后输出

Promise

链式调用

    • Promise的链式调用 finally 后依然可以调用 then。同理 finally后依然可以调用 catch

Promise.all

Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。

    let Promise1 = new Promise(function(resolve, reject){})
    let Promise2 = new Promise(function(resolve, reject){})
    let Promise3 = new Promise(function(resolve, reject){})
    
    let pAll = Promise.all([Promise1, Promise2, Promise3])
    
    pAll.then(()=>{
      // 三个都成功则成功  
    }, ()=>{
      // 只要有失败,则失败 
    })

Promise.race

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

    let Promise1 = new Promise(function(resolve, reject){})
    let Promise2 = new Promise(function(resolve, reject){})
    let Promise3 = new Promise(function(resolve, reject){})
    
    let pRace = Promise.race([Promise1,Promise2,Promise3])
    
    pRace.then(()=>{
        //第一个Promise成功走这里
    },()=>{
        //第一个Promise失败走这里
    })

题目:

new Promise((res,rej)=>{
    console.log('promise')
    res()
}).then(()=>{
    console.log('then');
    res()//这个then没有输出
    rej()//调用catch
    res()//如果catch后边有then,则调用catch之后的then
})
.then(()=>{
     console.log('thenA')//没有调用   
})
.catch(()=>{
    console.log('catch')//被rej调用
})
.then(()=>{
    console.log('thenB')//被rej后边的res调用
})

/**
输出结果
promise
then
catch
thenB
*/