一篇文章搞懂Promise基本用法

promise解决异步编程:

1. 旧方案:回调函数
2. Promise:是一个构造函数,内部封装异步操作
异步操作主要包括:fs文件读取操作,定时器,数据库操作,AJAX
3. promise新建之后会立即执行

promise
异步操作:
文件读取—用promise封装文件读取操作----02-fs文件读取.js
AJAX------用promise封装AJAX发送网络请求操作-03-ajax.html

promise构造函数的方法:
then/catch/finally ---p实例可以使用
Promise对象的方法:
                resolve/reject
                all/race
                allSettled
                any

一、基础用法

 let p = new Promise(function(resolve,reject){
    if(true){
        resolve()
    } else {
        reject()
    }
  })

resolve函数的作用

1. 将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved)
2. 在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用

1. 将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected)
2. 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

二、实例对象的属性

promise的状态–实例对象的一个属性【promiseState】

 
 pending 未决定的
 resolve /fullfilled 成功
 reject 失败

promise对象的值–实例中的另一个属性【PromiseResult】

保存着对象【成功/失败】的结果
resolve
reject

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ev5ftPXq-1675172227807)(assets/1.jpg)]

三、promise流程图

在这里插入图片描述

四、promise实例方法then/catch/finally

p.then方法


    getJSON("/posts.json").then(function(json) {
    return json.post;
    }).then(function(post) {
    // ...
    });
    then方法的链式调用:
    第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

p.catch方法

    p.then((val) => console.log('fulfilled:', val))
    .catch((err) => console.log('rejected', err));

    // 等同于
    p.then((val) => console.log('fulfilled:', val))
    .then(null, (err) => console.log("rejected:", err));

五、Promise对象方法 resolve/reject/all/race/allSettled

Promise.resolve方法

  1. Promise.resolve(‘foo’) 等价于 new Promise(resolve=>resolve(‘foo’))
  2. 如果传入的参数是:非promise类型的对象,则返回的结果为成功的promise对象
  3. 如果传入的参数是Promise对象,则参数的结果决定了resolve的结果
        let p1 = Promise.resolve('foo')
        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            reject('错误')
        }))
        console.log('promise的resolve方法', p1, p2);
        // 错误捕获
        p2.catch(error => {
            console.log('失败原因', error);

        })

Promise.reject 方法

    const p = Promise.reject('出错了'); 
    // 等同于
    const p = new Promise((resolve, reject) => reject('出错了'))

    p.then(null, function (s) {
    console.log(s)
    });
    // 出错了
    console.log(p) 

    // 上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。
    // Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。

    Promise.reject('出错了')
    .catch(e => {
    console.log(e === '出错了')
    })
    // true

Promise.all/race方法

接受参数是一个数组
p1,p2,p3是promise实例
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,
此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,
此时第一个被reject的实例的返回值,会传递给p的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)

–race用法基本同all

    promise
    .then(result => {···})
    .catch(error => {···})
    .finally(() => {···});

Promise.allSettled

使用场景:
有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。

与race类似,接受[p1,p2,p3]作为参数
可以等待所有的p结果出来之后返回,一个fullfilled则结果为fullfilled,全部为reject才为reject

const p1 = Promise.resolve(42);
const p2 = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([p1, p2]);

allSettledPromise.then(function (results) {
  console.log(results);
});
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]

它的回调函数接收到的参数是数组results,
该数组的每个成员都是一个对象,对应传入Promise.allSettled()的数组里面的两个 Promise 对象

使用实例:

const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ];
const results = await Promise.allSettled(promises);

// 过滤出成功的请求
const successfulPromises = results.filter(p => p.status === 'fulfilled');

// 过滤出失败的请求,并输出原因
const errors = results
  .filter(p => p.status === 'rejected')
  .map(p => p.reason);

关键问题:

1. 如何修改promise对象的状态?

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sVjzad8h-1675172227808)(assets/2.jpg)\]](https://img-blog.csdnimg.cn/94ddcdcb39e042d18b58171ca8528df5.png)

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

当promise改变为对应状态时都会调用
![在这里插入图片描述](https://img-blog.csdnimg.cn/97fefb74d6cf4d9b819723cb2c348055.png)

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

都有可能。
如果执行器函数excutor中包裹的是异步任务例如定时器(resolve()),此时先指定回调函数,当状态发生改变的时候,
回调函数会调用。

![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ycVDh9KO-1675172227811)(assets/4.jpg)\]](https://img-blog.csdnimg.cn/675c464408774c6ca16c9b0b4f6a2e0d.png)

在这里插入图片描述

4. p.then()返回的新promise的结果由什么决定?

简单回答:由then执行的回调函数的执行结果决定。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vz4V2MAe-1675172227811)(assets/6.jpg)]

在这里插入图片描述

5. promise如何串联多个任务?

promise的then()返回一个新的promise,可以开成then()的链式调用
通过then串联多个同步或者异步任务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPFYTMub-1675172227811)(assets/8.jpg)]

6. promise异常穿透?

// catch在最后捕获异常,异常穿透
p.then(value=>{}).then(value=>{}).catch(reason=>{
    console.log('捕获异常')
})

7. 如何中断promise链?

promise链:.then.then.then ----then 的链式调用
当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数。
解决办法:在回调函数中返回一个pending状态的promise对象

p.then(value=>{
    return new Promise(()=>{}) // pending 状态的promise--中断-后面的then不再执行
}).then(value=>{}).then(value=>{})

async与await函数

1. async函数

    async函数的返回值是一个promise对象
    返回的promise对象结果由async函数执行的返回值决定
    和then方法的返回规则一样

2. await函数

    await必须写在async函数当中
    await函数后面一般跟的是promise对象,也可跟其他的值
    await的promise如果失败了,会抛出异常,需要通过try...catch   进行捕获处理

在这里插入图片描述

async function handler(){
    try{
      await new Promise((resolve,reject)=>{
        throw "error"
      })
    }catch(e){
    console.log('抛出错误',e)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值