欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > Promise详解及面试例题

Promise详解及面试例题

2024/10/25 23:34:15 来源:https://blog.csdn.net/2301_78675670/article/details/141255052  浏览:    关键词:Promise详解及面试例题

1、Promise的基本概念

1.1、基本概念:

  1. PromiseJavaScript中的一种用于处理异步操作的对象
  2. 可以把它想象成一个“承诺”——程序承诺会在未来的某个时间点完成某件事(比如从服务器获取数据),但是,并不立即返回结果。

1.2、Promise的状态:

Promise 有三种状态:

  1. Pending(进行中): 承诺还没有完成,也没有失败,它正在等待某件事情发生。
  2. Fulfilled(已完成): 承诺成功地完成了,并且返回了一个结果。
  3. Rejected(已失败) : 承诺未能完成,发生了某种错误或问题。

1.3、生活场景示例:

假设小明让小红帮忙买咖啡,小红答应了,这时,这个“答应”的过程就是一个Promise,它可能有三种状态:

  • Pending:小红还在咖啡店排队,咖啡还没买到手。
  • Fulfilled:小红已经买到咖啡,并且把咖啡给了小明。
  • Rejected:小红因为某种原因没法买到咖啡,告诉小明:“抱歉,没买到”。

2、Promise的链式调用规则

Promise的链式调用是指:

  1. 在一个Promise.then() 方法中返回一个新的Promise,然后可以继续在这个新的Promise上调用.then() 方法
  2. 这种方式可以:让我们可以把多个异步操作串联起来,依次处理,避免回调地狱。
  1. .then()返回的是一个新的Promise
    • 每次调用.then() 方法后,你都会得到一个新的Promise
    • 这使得你可以在下一个.then()里继续处理上一个.then()的结果。
  2. .then() 的回调函数可以返回值:
    • 如果回调函数返回的是一个普通的值(而不是 Promise),这个值会被包装成一个已经完成的 Promise,并传递给下一个 .then()
  3. 回调函数返回的是Promise
    • 如果回调函数返回的是一个Promise,那么下一个.then()将会等待这个Promise完成,然后继续处理结果。
  4. 错误传递:
    • 如果任何一个.then()中发生错误(包括抛出异常或返回一个被拒绝的 Promise),这个错误会被传递到后面最近的.catch()中处理。

3、Promise的静态方法

  1. Promise.resolve(value):
    • 用来快速创建一个已经完成的Promise,并将给定的value作为结果。
    • 适用于:将一个普通的值或非Promise的结果转换为Promise
  2. Promise.reject(reason):
    • 用来快速创建一个被拒绝的Promise,并将给定的 reason 作为错误原因。
    • 适用于:将一个错误或失败的结果转换为 Promise
  3. Promise.all(iterable):
    • 接受一个可迭代对象(通常是一个数组)作为参数,其中每个元素都是一个 Promise。
    • 只有当所有的 Promise 都完成时,返回的 Promise 才会被完成,结果是一个包含所有结果的数组
    • 如果有任何一个Promise被拒绝,Promise.all会立即返回一个被拒绝的Promise
  4. Promise.race(iterable):
    • 接受一个可迭代对象,其中每个元素也是一个 Promise。
    • 返回的 Promise 会在第一个 Promise 完成或拒绝时,采用这个 Promise 的结果或错误。
    • 适用于:你只关心最先完成的异步操作的场景
  5. Promise.allSettled(iterable):
    • 接受一个可迭代对象,每个元素是一个 Promise。
    • 返回的 Promise 会等待所有的 Promise 都结束(无论是完成还是拒绝),并返回一个数组,数组中的每一项都是一个对象,表示每个 Promise 的状态和结果。
    • 适用于:你希望等待所有 Promise 结束后,处理每个 Promise 的结果
  6. Promise.any(iterable):
    • 接受一个可迭代对象,每个元素是一个 Promise。
    • 返回的 Promise 会在第一个成功(fulfilled)的 Promise 完成时被完成。如果所有的 Promise 都被拒绝,返回的 Promise 会被拒绝,错误信息是所有错误的一个数组。
    • 适用于:你只关心最先成功的异步操作的场景

4、async和await

  • asyncawaitJavaScript中用于处理异步操作的关键字
  • 它们让你能够像写同步代码那样编写异步代码,使得代码更加清晰和易读。

4.1、async 函数

  • async是用来定义一个异步函数关键字
  • 一个函数一旦被定义为 async,它就会自动返回一个 Promise,而不论你在函数中实际返回的是什么。

4.2、await 关键字

  • await只能在async函数内部使用。
  • 它用于等待一个Promise完成,并获得Promise解决的值
  • 简单理解:
    • 使用await,就像在告诉JS:“等一下,等这个Promise完成了,再继续执行后面的代码。”

4.3、async 和 await 的好处:

  • 更易读:它让你可以像写同步代码一样写异步代码,不需要再用.then()链式调用,代码逻辑更直观
  • 错误处理:你可以使用try...catch语句来处理异步操作中的错误,这样比处理Promise.catch()更加清晰。

5、事件循环中,Promise进入的是哪些事件队列

以下:包含一些常规的事件队列总结

  1. setTimeout的回调:宏任务(macro task)
  2. setInterval的回调:宏任务(macro task)
  3. promisethen函数回调:微任务(micro task)
  4. requestAnimationFrame的回调:介于宏任务和微任务之间,但通常被归类为宏任务(macro task)
  5. 事件处理函数:宏任务(macro task)

6、面试例题

根据下列代码,判断代码输出的结果是什么:

// 下面代码的输出结果是什么 => 先后打印:1、2、4、3const promise = new Promise((resolve, reject) => {console.log(1);resolve();console.log(2);});promise.then(() => {
// 这里不先打印`3`是因为:promise里的then回调会进入"微任务队列",它必须等待全局(同步)代码执行完成后,再执行微队列里的代码console.log(3); });console.log(4);
// 下面代码的输出结果是什么 => 1、5、2、3、4const promise =new Promise((resolve,reject)=>{// 1)同步代码先执行 => 打印1console.log(1);// 2)延时器进入宏队列,等待处理// 5)处理宏队列任务setTimeout(()=>{// 5-1、打印输出2console.log(2);// 5-2、将Promise对象状态改为成功状态 => 回调函数进入微队列,但,需要等到当前宏队列任务完成后才能执行微队列任务resolve();// 5-3、打印输出3console.log(3);}); });// 3)因为promise对象此时还是pending状态,没有满足成功状态,此时这里代码也是不执行的,也不会放入微队列promise.then(()=>{// 6)处理微队列任务 => 打印输出4console.log(4);});// 4)执行同步代码 => 打印5console.log(5);
// 下面代码的输出结果是什么const promise1 = new Promise((resolve, reject)=>{setTimeout(()=>{resolve()},1000)})const promise2 = promisel.catch(()=>{return 2;})
// 因为:它们还在等待`resolve`或`reject`状态// 1)打印:promise1 Promise{<pending>} // 2)打印:promise2 Promise{<pending>}console.log('promise1', promise1)console.log('promise2', promise2)setTimeout(()=>{
// 因为:`promise1`被`resolve`后,状态变为`fulfilled`,且`resolve()`没有传递值,所以`fulfilled`的值是`undefined`。// 3)打印:promise1 Promise{<undefined>}// 4)打印:promise2 Promise{<undefined>}console.log('promise1', promise1)console.log('promise2',promise2)},2000)
// 下面代码的输出结果是什么 => 0、2、1async function m(){// 1)立即执行,打印 0console.log(0)// 2)遇到await,m函数则暂停执行,将返回的1包装成一个已解决的Promise,这时控制权返回到主线程,继续执行同步代码const n = await 1;// 4)等待获取l的结果后再执行console.log(n);}m();// 3)同步代码立即执行,打印2console.log(2);
// 下面代码的输出结果是什么 => 0、3、1、2async function m(){// 1)立即执行,打印0console.log(0)// 2)await表达式会立即执行(即 Promise.resolve(1)),但,会让出执行线程const n = await 1;// 5)在微任务队列中执行,await完成后打印 1console.log(n);}(async ()=>{// 4) 调用 m(),进入 m 函数,暂停在 await 处await m();// 6) 在 m() 执行完后,打印 2console.log(2);})();// 3) 同步代码立即执行,打印 3   console.log(3);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com