Promise 面试题整理

16 篇文章 0 订阅
本文通过实例讲解Promise的构造函数、then与catch的行为,以及常见误区,包括状态转移、链式调用、错误处理和非函数参数。涉及Promise的同步异步执行、链式调用的时机和Promise.resolve的应用。
摘要由CSDN通过智能技术生成

基础输出题

  1. 题目1
const promise = new Promise((resolve, reject) => {
    console.log(1)
    resolve()
    console.log(2)
})
promise.then(() => {
    console.log(3)
})
console.log(4)

//  1 2 4 3

记住 new Promise 里的参数函数,是同步被执行的,故而先输出 1,2.
resolve 后还需要等待进入下一个事件循环。then 把参数函数推入微任务队列,并不直接执行。
输出 4,接着事件循环进入下一轮,输出 3.

  1. 题目2
    给出一个 promise
var promise = new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 3000)
})

请问这三种有何不同?

// 1
promise.then(() => {
  return Promise.resolve(2);
}).then((n) => {
  console.log(n)
});

// 2
promise.then(() => {
  return 2
}).then((n) => {
  console.log(n)
});

// 3
promise.then(2).then((n) => {
  console.log(n)
});

1.输出2。Promise.resolve 就是一个 Promise 对象就相当于返回了一个新的 Promise 对象。然后在下一个事件循环里才会去执行 then
2.输出2。和上一点不一样的是,它不用等下一个事件循环。
3.输出1。then 和 catch 期望接收函数做参数,如果非函数就会发生 Promise 穿透现象,打印的是上一个 Promise 的返回。

  1. 题3
let a;
const b = new Promise((resolve, reject) => {
  console.log('promise1');
  resolve();
}).then(() => {
  console.log('promise2');
}).then(() => {
  console.log('promise3');
}).then(() => {
  console.log('promise4');
});

a = new Promise(async (resolve, reject) => {
  console.log(a);
  await b;
  console.log(a);
  console.log('after1');
  await a
  resolve(true);
  console.log('after2');
});

console.log('end');

答案

promise1
undefined
end
promise2
promise3
promise4
Promise { pending }
after1

第一个输出 promise1,是因为 Promise 里的方法立即执行。接着调用 resolve,只不过 then 里的方法等下一个周期
第二个输出 undefined,是因为立即执行执行 a 内部的方法,先 console.log(a),但此时的 a 还没赋值给左边的变量,所以只能是 undefined。然后 await b 就得等下一个周期执行了。
第三个输出 end,自然不意外。
接着输出 promise2,promise3,promise4,是因为 await b 等待他执行完了,才轮到 a 内部继续执行。
输出 Promise { pending },脑筋转了以下才想通,事件都进入了循环了,a 肯定已经被赋值成了 Promise 对象。所以第二遍 console.log(a),自然就输出这个了。
输出 after1 不奇怪。
await a 时,a 是必须等待 Promise 的状态从 pending 到 fullfilled 才会继续往下执行,可 a 的状态是一直得不到更改的,所以无法执行下面的逻辑。只要在 await a 上面加一行 resolve() 就能让后面的 after 2 得到输出

  1. 题4
const promise = new Promise((resolve, reject) => {
  resolve('success1');
  reject('error');
  resolve('success2');
});

promise
  .then((res) => {
    console.log('then: ', res);
  })
  .catch((err) => {
    console.log('catch: ', err);
  });

牢牢记住 Promise 对象的状态只能被转移一次,resolve(‘success1’) 时状态转移到了 fullfilled 。后面 reject 就调用无效了,因为状态已经不是 pending。

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

没有抛出错误和异常,只是 return 了一个对象,哪怕他是 Error 对象,那自然也是正常走 then 的链式调用下去了,不会触发 catch。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值