面试中Promise相关问题

这篇博客详细探讨了Promise的异步机制、状态变化、同步顺序、Promise.all的使用以及在异常处理中的策略。还分析了Promise.all与Promise.race的区别及适用场景,结合面试题提供了深入的理解。
摘要由CSDN通过智能技术生成

结合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的回调函数。

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

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个方法拿数据,哪个方法数据拿的快,就先拿哪个方法的数据。

JavaScriptPromise是一种处理异步操作的对象,它允许你将异步操作写得更加接近同步代码的形式,这样代码更加清晰易懂。Promise有三种状态:pending(等待)、fulfilled(已成功)和rejected(已失败)。一旦Promise被解决(fulfilled或rejected),它就固定在那个状态,不能再次改变。 以下是几个常见的JavaScript Promise面试题: 1. Promise的`.then()`方法和`.catch()`方法分别有什么作用? `.then()`方法用于处理Promise成功后的回调函数,它可以接受两个参数,第一个参数是Promise成功时调用的函数,第二个参数是可选的,如果Promise被拒绝(rejected),则调用的函数。`.catch()`方法则专门用来处理Promise被拒绝的情况。 2. 如何创建一个Promise? 可以通过new Promise()构造函数来创建一个新的Promise实例。构造函数接受一个执行器(executor)函数作为参数,该函数接受两个参数:resolve和reject。resolve和reject都是函数,分别用来将Promise的状态从pending改为fulfilled或rejected。 ```javascript let promise = new Promise((resolve, reject) => { // 异步操作代码 if (/* 成功条件 */) { resolve("操作成功"); } else { reject("操作失败"); } }); ``` 3. 如何同时运行多个异步操作,并在它们全部完成后再执行后续操作? 可以使用`Promise.all()`方法。它接受一个Promise对象的数组作为参数,只有所有的Promise都成功解决后,它才会解决;如果任何一个Promise被拒绝,它就会被拒绝。 ```javascript let promise1 = Promise.resolve(3); let promise2 = 42; let promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then(values => { console.log(values); // [3, 42, "foo"] }); ``` 4. 如何处理Promise发生的错误? 可以在`.then()`方法之后连着使用`.catch()`方法来捕获和处理错误。如果在`.then()`发生的任何错误,都会被传递到下一个`.catch()`。 ```javascript promise .then(result => { // 处理结果 }) .catch(error => { // 处理错误 }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值