通过案例,分析Promise的执行结果

60 阅读2分钟

第一题

题目

写出下面代码的执行结果

Promise.resolve().then(() => {
  console.log('promise1');
  const timer2 = setTimeout(() => {
    console.log('timer2')
  }, 0)
});
const timer1 = setTimeout(() => {
  console.log('timer1')
  Promise.resolve().then(() => {
    console.log('promise2')
  })
}, 0)
console.log('start');

执行步骤

  • 首先,代码按照顺序执行,自身就是一个宏任务
  • Promise.resolve().then是一个微任务,加入微任务队列
  • 执行timer1,它是一个宏任务,加入宏任务队列
  • 继续执行下面的同步代码,打印出start
  • 第一轮宏任务就执行完了
  • 开始执行微任务,打印出promise1
  • 遇到timer2,它是一个宏任务,将其加入宏任务队列(timer1、timer2)
  • 第一轮的微任务就执行完了
  • 开始执行第二轮宏任务
  • 执行定时器timer1,打印timer1
  • 遇到Promise,它是一个微任务,加入微任务队列
  • 第二轮宏任务执行完毕
  • 开始执行微任务队列中的任务,打印promise2
  • 第二轮的微任务执行结束
  • 最后执行宏任务timer2定时器,打印出timer2

结果

'start'
'promise1'
'timer1'
'promise2'
'timer2'

第二题

题目

写出下面代码的执行结果

Promise.resolve().then(() => {
  return new Error('error!!!')
}).then(res => {
  console.log("then: ", res)
}).catch(err => {
  console.log("catch: ", err)
})

执行步骤

  • 第一个then 正常处理,返回fulfilled状态的结果
  • 第二个then 正常执行,打印结果

你需要知道:

如果回调函数的返回结果是非promise类型的属性,则then方法返回的promise对象的状态为成功fulfilled

因此这里的return new Error('error!!!')被包裹成了return Promise.resolve(new Error('error!!!')), 因此它被then捕获而不是catch。

结果

then:  Error: error!!!

第三题

题目

写出下面代码的执行结果

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
  })
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')

执行步骤

  • 首先程序打印srcipt start
  • 进到async1() 方法,打印async1 start
  • 执行await方法,打印promise1,后续代码放入微任务中
  • 任务结束,跳出async1()
  • 打印script end
  • 由于Promise是没有返回值的,微任务中代码无法执行,包括then()

需要注意的是在async1await后面的Promise是没有返回值的,也就是它的状态始终是pending状态,所以在await之后的内容是不会执行的,也包括async1后面的 .then

结果

script start
async1 start
promise1
script end

关于这个题目,有人会质疑

1、async1()是一个普通函数,为什么可以使用then()?

基础没有学好,async定义的函数会默认返回一个Promise对象,所以没问题

2、如何写,才能返回出所有结果?

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1');
    resolve(1);
  });
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')

执行结果

srcipt start
async1 start
promise1
srcipt end
async1 success
async1 end