面试中Promise相关问题

结合bilibili和小米和阿里的面试题中出现的与Promise对象相关的问题自己试着做了一些回答,涉及的有以下几个问题。

  1. 详述Promise的异步机制?
  2. Promise有几种状态?
  3. Promise如何满足多个异步进程的同步顺序?
  4. Promise.all的用法
  5. 如何让Promise.all在抛出异常后依然有效?
  6. Promise.all与Promise.race的区别?应用场景?

1.Promise的异步机制

1.通过Promise对象可以获取异步操作的消息。Promise构造函数接受一个函数作为参数,该函数的两个参数又分别是resolverejectresolve函数的作用是将Promise对象的状态从未完成变成完成,在异步操作成功时调用,并且将异步操作的结果作为参数传递出去。reject函数是将Promise 对象的状态从未完成变成失败,在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。

2.Promise实例生成以后使用then方法分别指定resolvedrejected状态的回调函数。Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。有多个异步任务就可以写多个then方法。这时前一个回调函数有可能返回的还是一个promise对象(即有异步操作),这时后一个回调函数就会等待该Promise对象的状态发生变化,才会被调用。

2.Promise的状态

Promise有三种状态,分别是:

  1. pending:进行中
  2. fulfilled:已成功
  3. rejected:已失败

注意:只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态。

3.Promise如何满足多个异步进程的同步顺序

可以使用then方法链式调用。

采用链式的then,可以指定一组按照次序调用的回调函数,这时,前一个回调函数有可能返回的还是一个promise对象(即有异步操作),这时后一个回调函数就会等待该Promise对象的状态发生变化,才会被调用。这就满足了多个异步进程的从上到下执行的同步顺序。

4.Promise.all的用法

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

语法:

const p = Promise.all([p1, p2, p3]);

上面p1,p2,p3都是promise实例,只有所有实例p1,p2,p3的状态都变为fulfilled,p的状态才会变成fulfilled

此时,实例p1 ,p2, p3的返回值组成一个数组,传递给p的回调函数。

扫描二维码关注公众号,回复: 9257974 查看本文章

例如:如果有多个异步请求,但是最终用户想要得到的结果是多个异步结果合并到一起的完整结果。代码如下:

let p1 = new Promise((resolve, reject) => {
  resolve('p1成功')
})

let p2 = new Promise((resolve, reject) => {
  resolve('p2成功')
})

let p3 = new Pomise((resolve,reject)=>{
	resolve('p3成功')
})

Promise.all([p1, p2,p3]).then((res) => {
  console.log(res)               //['p1成功', 'p2成功',p3成功]
}).catch((error) => {
  console.log(error)
})

5.如何让Promise.all在抛出异常后依然有效

方法:给每个作为Promise.all参数的Promise实例定义catch方法。

那么某个promise实例一旦被rejected,就会进入自己的catch方法,该实例执行完catch方法后,也会变成resolved。那么就不会触发Promise.allcatch方法,Promise.all在抛出异常后也依然有效。

例如:

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

上面代码中,p1会resolved,p2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。

如果p2没有自己的catch方法,就会调用Promise.all()catch方法。

详细请参考阮一峰老师的es6文章。

6.Promise.all与Promise.race的区别?应用场景?

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.all与Promise.race的区别:

  1. Promise.all:返回一个promise对象,接收的多个promise实例对象都成功了,Promise.all返回的promise对象才会成功。

    应用场景:一个功能的数据,要有多个ajax请求拼接才能得到最终的数据。

  2. Promise.race:返回一个promise对象,这个promise对象只会取决于第一个完成的promise实例的结果。

    应用场景:通过2个方法拿数据,哪个方法数据拿的快,就先拿哪个方法的数据。

发布了111 篇原创文章 · 获赞 120 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/w1418899532/article/details/99197862