前端系列 | 如何更好的理解Promise对象

2023-03-08 20:15:33 浏览数 (2)

promise是什么?

Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10 和 Windows 的 Edge 14 版本以上浏览器才开始支持 ES6 特性。

promise 用途

1、主要用于异步计算 2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果 3、可以在对象之间传递和操作promise,帮助我们处理队列

Promise 对象两个特点

1、对象的状态不受外界影响。

Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

“注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

为什么需要Promise ?

需求

通过AJAX请求id ,再根据id请求用户名.再根据用户名,再根据用户名获取email。

回调地狱

回掉函数中嵌套回调,Promise解决了回调地狱。

Promise 的基本使用

语法

代码语言:javascript复制
new Promise(( reslove, reject ) =>{})
  • Promise接受一个函数作为参数
  • 在参数函数中节后两个参数
    • solve: 成功函数
    • reject: 失败函数

Promise实例

promise实例有两个属性

  • state: 状态
  • result: 结果

Promise的状态

  • 第一种状态: pending
  • 第二种状态: fulfilled
  • 第三种状态: rejected

Promise状态的改变

示例1

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //resolve(): 调用函数, 使当前Promise对象的状态改成fulfilled
  reslove();
})
console.dir(p) // fulfilled

例2

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //resolve(): 调用函数, 使当前Promise对象的状态改成fulfilled
  //reject(): 调用函数, 使当前Promise对象的状态改成rejected
  //reslove();
  reject()
})
console.dir(p) 

Promise状态的改变使一次性的

  • resolve(): 调用函数, 使当前Promise对象的状态改成fulFilled
  • reject(): 调用函数,使当前Promise对象状态改成rejected

Promise 的结果

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //通过调用reslove,传递参数,改变 当前Promise对象的结果
  resolve("成功的结果");
  //reslove();
  //reject("失败的结果")
})
console.dir(p) 

Promise的方法

then方法

示例 1

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //通过调用reslove,传递参数,改变 当前Promise对象的结果
  //reslove("成功的结果");
  reject("失败的结果")
})

//then方法函数
//参数
//两个参数都是函数
//返回值: 是一个Promise对象
p,then(()=>{
  //当Promise的状态使fulfilled时执行
  console.log("成功的回调")
},()=>{
  // 当Promise的状态时rejected时, 执行
  console.log("失败时调用")
})
console.dir(p) 

实例 2

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //通过调用reslove,传递参数,改变 当前Promise对象的结果
  //reslove(123);
  reject("失败的结果")
})

//then方法函数
//参数
//两个参数都是函数
//返回值: 是一个Promise对象
p,then((value)=>{
  //当Promise的状态使fulfilled时执行
  console.log("成功的回调",value)
},(err)=>{
  // 当Promise的状态时rejected时, 执行
  console.log("失败时调用",err)
})
console.dir(p) 

“在then方法的参数函数中,通过形参使用Promise对象的结果

then方法返回一个新的Promise实例,状态时pending

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  //通过调用reslove,传递参数,改变 当前Promise对象的结果
  //reslove(123);
  reject("失败的结果")
})

//then方法函数
//参数
//两个参数都是函数
//返回值: 是一个Promise对象
p,then((value)=>{
  //当Promise的状态使fulfilled时执行
  console.log("成功的回调",value)
},(err)=>{
  // 当Promise的状态时rejected时, 执行
  console.log("失败时调用",err)
})
console.dir(p) 

Promise的状态不改变,不会执行then里的方法

代码语言:javascript复制
//如果Promise的状态没有改变,then里的方法不会执行
const p = new Promise((resolve, reject) => {
  
}).then.((value) => {
 console.log("成功")
},(reason) => {
console.log("失败")
})

then方法中,通过return将返回的Promise实例改为fulfilled状态

代码语言:javascript复制
//如果Promise的状态改变,then里的方法不会执行
const p = new Promise((resolve, reject) => {
  
})
const t = p.then.((value) => {
  console.log("成功")
  //使用return可以将t实例的状态改为fulfilled
  return 123
},(reason) => {
  console.log("失败")
})
t.then.((value) => {
   console.log("成功2",value)
},(reason) => {
   console.log("失败2")
})

在then方法中,出现代码错误,将返回的Promise实例改为rejected状态

代码语言:javascript复制
//如果Promise的状态改变,then里的方法不会执行
const p = new Promise((resolve, reject) => {
  
})
const t = p.then.((value) => {
  console.log("成功")
  //使用return可以将t实例的状态改为fulfilled
  return 123
},(reason) => {
  //如果这里代码出错,会将t实例的状态改为rejected
  console.log("失败")
})
t.then.((value) => {
  console.log("成功2",value)
},(reason) => {
   console.log("失败2")
})

catch方法

示例

代码语言:javascript复制
const p = new Promise((resolve, reject) => {
  // reject()
  //console.log(a)
  throw new Error("出错了");
})

//思考: catch中的参数函数在什么时候被执行
//1. 当Promise的状态改为rejcted.被执行
//2. 当Promise执行体重出现代码错误时,被执行
p.catch((reason => {
 console.log("失败", reason)
})
console.log(p);

0 人点赞