Promise

Promise

Promise 是异步编程的一种解决方案

从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。

promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

1:Promise基本介绍

从语法上来说: Promise是一个构造函数

从功能上来说: promise对象用来封装一个异步操作并可以获取其成功/失败的结果值

1.1:什么是异步函数

异步编程包括但不限于以下几种:

  1. fs·文件操作
  2. 教据库操作
  3. AJAX
  4. 定时器

之前的异步函数往往是使用回调函数的方式完成,for一个exemple

ajax

$.get("/serve",()=>{})

定时器

setTimeout(()=>{},2000);
1.2:为什么要用Promise
(1)指定回调函数方式更加灵活

回调函数:必须在启动异步任务前指定

promise:启动异步任务=>返回promie,对象=>给promise对象绑定回调函数(甚至可以在异步任务结束后指定多个回调函数)

(2)支持链式调用,解决回调地狱的问题

什么是回调地狱

在这里插入图片描述

这不便于代码阅读,也不便于异常处理

1.3:Peomise基操介绍
(1)Promise基础案例
// Promise形式实现(setTimeout为1秒后触发)
// resolve解决函数类型的数据
// reject拒绝函数类型的数据
const p = new Promise((resolve,reject) =>{
    setTimeout(() =>{
        //获取从1 - 100的一个随机数let n = rand(1,100);//判断
        if(n <= 30){
            resolve(n); // 将promise对象的状态设置为『成功』
        }else{
            reject(n); // 将promise对象的状态设置为『失败』
        }
    }
}.1000);});
// 调用.then方法,两个函数形式的参数,成功就调用第一个,失败就调用第二个
p.then((value)=>{
    alert("随机数小于30,随机数为"+value);
},(reason)={
    alert("随机数大于30,随机数为"+reason);
})

(4)Peomise进行fs读取文件的回调

//Promise形式进行fs读取文件的回调
let p = new Promise((resolve , reject) =>{
	fs.readFile( './data/content.txt', (err, data) =>{
        //如果出错
        if(err) reject(err);
        resolve(data);	//如果成功
    });
});
//调用then
p.then((value)=>{
	console.log(value.toString());
},(reason)=>{
	console.log(reason);
})

1.:4:Promise的属性

(1)PromiseState(状态)

1)Promise只有三种状态

实例对象中的一个属性 Promisestat

  1. pending——未决定的《初始状态》
  2. resolved / fullfilled——成功
  3. rejected——失败

2)Promise状态改变

  1. peiding变为resolved
  2. pending变为rejected

说明:只有这2种,且一个promise对象只能改变一次

无论变为成功还是失败,都会有一个结果数据

成功的结果数据一般称为value,失败的结果数据一般称为reason

(2)PromiseResult(对象的值)

实例对象中的另一个属性『PromiseResult』

保存着对象『成功/失败』的结果

只有resolve函数和reject函数可以对这个结果进行操作或者使用

1.5:Promise的工作流程

就是成功调第一个回调函数,失败调第二个回调函数

在这里插入图片描述

2:Promise API

2.1:Promise"实例"对象的API
(1)PromiseI构造函数

PromiseI构造函数:Promise (excutor) {}

(1)executor函数:执行器(resolve, reject)=>{}

(2) resolve函数:内部定义成功时我们调用的函数value =>{}

(3)reject函数:内部定义失败时我们调用的函数reason=>{}

说明:executor会在 Promise内部立即同步调用,异步操作在执行器中执行

(2)实例对象.then

Promise.prototype.then方法:(onResolved, onRejected)=>{}

  1. onResolved函数:成功的回调函数(value)=>{}
  2. onRejected函数:失败的回调函数(reason)=>{}

说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调,返回一个新的promise对象

(3)实例对象.catch

Promise.prototype.catch方法: (onRejected)=>{}

onRejected函数:失败的回调函数(reason)=>{}

2.2:Promise"函数"对象的API
(1)Promise.resolve

Promise.resolve方法:(value) =>{}

​ value:成功的数据或promise对象

说明:返回一个成功/失败的promise对象

  1. 如果传入的参数为非Promise类型的对象,则返回的结果为成功的promise对象
  2. 如果传入的参数为Promise对象,则参数的结果决定了resolve 的结果
(2)Promise.reject

Promise.reject 方法:(reason) =>{}

reason:失败的原因

说明:返回一个失败的promise对象

(3)Promise.all

Promise.all方法:(promises)=> {}

promises:包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败。

(4)Promise.race

Promise.race方法:(promises) =>{}

promises:包含n个promise的数组

说明:返回一个新的promise,第一个完成的 promise的结果状态就是最终的结果状态

3:Promise 关键问题

1:如何改变promise的状态?

(1)resolve(value):如果当前状态是pending就会变为resolved

(2)reject(reason):如果当前状态是pending就会变为rejected

(3)抛出异常throw:如果当前是pending就会变为rejected

2:一个promise指定多个成功/失败回调函数,都会调用吗?

如果使用then指定多个回调,是都会调用吗

当promise改变为对应状态时,这些回调都会调用(可以定义多个成功或者失败的回调)

3:改变promise状态和指定回调函数碓先谁后?

(1)都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调

(2)如何先改状态再指定回调?

  1. 在执行器中直接调用resolve()/reject
  2. 延迟更长时间才调用then()

(3)什么时候才能得到数据?

  1. 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
  2. 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
4:promise.then()返回的新promise的结果状态由什么决定?

由then()指定的回调函数执行的结果决定

如果抛出异常,新promise变为rejected, reason为抛出的异常

如果返回的是非promise的任意值,新promise变为resolved,value为返回的值如果返回的是另一个新promise,此promise的结果就会成为新promise的结果。

5:promise 如何串连多个操作任务?

(1)promise 的 then()返回一个新的promise,可以开成then()的链式调用

(2)通过 then的链式调用串连多个同步/异步任务

在这里插入图片描述

6:promise异常传透?

(1)当使用promise 的 then链式调用时,可以在最后指定失败的回调

(2)前面任何操作出了异常,都会传到最后失败的回调中处理

在这里插入图片描述

7:中断promise 链

(1)当使用promise 的 then链式调用时,在中间中断,不再调用后面的回调函数

(2)办法:在回调函数中返回一个pendding状态的promise对象(唯一的方法,只有是padding状态《状态不改变》会导致后面的回调均不执行)

4:Promise 自定义封装

5:async 和 await

5.1:async和await函数
async函数

(1)函数的返回值为promise对象

(2)promise对象的结果由 async函数执行的返回值决定,

  1. 如果返回值是非promise类型的对象,那么结果就是成功的Promise对象
  2. 如果返回结果是promise类型,那么结果就是该Promise对象
  3. 如果抛出异常,那么返回结果就是失败的Promise对象,值就是异常的原因
await函数
  1. await右侧的表达式一般为promise对象,但也可以是其它的值
  2. 如果表达式是promise对象, await返回的是promise成功的值
  3. 如果表达式是其它值,直接将此值作为await的返回值

await必须写在async函数中,但 async函数中可以没有await

如果await的 promise失败了,就会抛出异常,需要通过try…catch捕获处理

在这里插入图片描述

也可以Ajax请求封装成Promise

其实我们也可以不自己写ajax的请求函数,axios已经帮我们完成了这些问题

ise对象,但也可以是其它的值
2. 如果表达式是promise对象, await返回的是promise成功的值
3. 如果表达式是其它值,直接将此值作为await的返回值

await必须写在async函数中,但 async函数中可以没有await

如果await的 promise失败了,就会抛出异常,需要通过try…catch捕获处理

[外链图片转存中…(img-1UR0ZNsE-1667991386332)]

也可以Ajax请求封装成Promise

其实我们也可以不自己写ajax的请求函数,axios已经帮我们完成了这些问题

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Addam Holmes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值