Promise使用快速攻略

Promise解决什么问题

异步操作的回调地狱,可以让异步操作写起来,就像写同步操作一样

php 复制代码
// 异步操作的回调地狱问题
$.ajax({
    type: 'GET',
    url: '/a',
    data:{},
    success: res => {
        const id = res.data;
        $.ajax({
            type: 'GET',
            url: '/b',
            data:{
                id,
            },
            success: res => {
                const username = res.data;
                $.ajax({
                    type: 'GET',
                    url: '/b',
                    data:{
                        id,
                    },
                    success: res => {
                        const username = res.data;
                        
                    }
                });
            }
        });
    }
});
php 复制代码
// 使用promise后,就像写同步操作一样写异步操作
const p = new Promise((resolve, reject) => {
    $.ajax({
        type: 'GET',
        url: '/a',
        data:{},
        success: res => {
            resolve(res);
        }
        error: res => {
            reject(res)
        }
     })
}.then(res => {
    $.ajax({
        type: 'GET',
        url: '/b',
        data:{},
        success: res => {
            resolve(res);
        }
        error: res => {
            reject(res)
        }
     })
}).then(res => {
    $.ajax({
        type: 'GET',
        url: '/c',
        data:{},
        success: res => {
            resolve(res);
        }
        error: res => {
            reject(res)
        }
     })
}).
kotlin 复制代码
// 结合async await,可进一步消除回调的影子
const resA = await axios.get('/a');
const resB = await axios.get('/b', { id: resA.data.data });
const resC = await axios.get('/c', { username: resB.data.data });
 

Promise的基本使用

Promise是构造函数,用new实例化

Promise是一个构造函数,使用new进行实例化。

该构造函数入参是一个函数,函数包含两个参数:resolve/reject,均为函数,接受一个参数,即为promise的结果

javascript 复制代码
const p = new Promise((resolve, reject) => {
    
});

Promise实例的3种状态

  • 初始状态pending
  • 已完成fulfilled
  • 已失败rejected

Promise状态变化是一次性的,即pending=>fulfilled,或者pending=>rejected。当resolved(fulfilled/rejected)后,无法再变更为其他状态,即Promise状态不可逆。

状态变更&结果返回

  1. => fulfilled

调用resolve函数

  1. => rejected

调用reject函数或者代码报错

javascript 复制代码
const p = new Promise((resolve, reject) => {
    resolve('success');
    // reject('failed'); // 不生效,promise状态不可逆
});
const p2 = new Promise((resolve, reject) => {
    reject('failed');
});

Promise常用方法


实例方法


🌟🌟🌟then方法

入参:

  • 两个函数,第一个为状态转为fulfilled时的成功回调,第二个为状态转为rejected时的失败回调(不常用)
  • 成功回调和失败回调的参数为前面promise中resolve或者reject的值

返回:一个新的promise实例

javascript 复制代码
const p = new Promise((resolve, reject) => {
    resolve('123');
    // reject('456'); 
}).then((val) => {}, (err) => {});

then方法的回调函数是异步操作,会在当前同步逻辑执行完之后执行(当前EventLoop的结尾,微任务)。但是注意使用Promise构造函数初始化Promise实例的入参数是同步执行的,不要搞混了。

javascript 复制代码
console.log('1')
const p = new Promise((resolve, reject) => {
    console.log('2');
    resolve('success');
}).then((val) => {
    console.log('3');
})
console.log('4');
// 输出:1,2,4,3

then方法返回的Promise实例通过return进行状态流转

javascript 复制代码
const p = new Promise((resolve, reject) => {
    resolve('success');
}).then((val) => {
})
const p1 = new Promise((resolve, reject) => {
    resolve('success');
}).then((val) => {
    return val;
})

🌟🌟 catch方法

入参:reject传递的值或者异常报错

返回:仍然返回一个新的promise

失败回调除了then的第二个参数之外,还可以调用catch方法,通常这种方法更常用。原因如下:

javascript 复制代码
const p = new Promise((resolve, reject) => {
    resolve('success');
}).then(val => {
    // ...
    // 发生异常
    // 
}, err => {
    // ❌无法捕获异常
}).catch(val => {
    // ✅能够捕获异常
});

🌟 finally方法

成功或者失败回调后,都会执行该函数,按需使用。


类方法


🌟🌟 Promise.resolve

返回一个fulfilled状态的promise实例,通常用于快速构造Promise,统一异步操作接口。以下是一个缓存优化的例子

kotlin 复制代码
let cachedData;
function getData() {
    if (cachedData) {
        return Promise.resolve(cachedData); // 直接返回缓存
    }
    return fetch('url').then(data => {
        cachedData = data;
        return data;
    });
}

或者某个同步任务耗时比较久,用来构造一个微任务,从而不阻塞主流程

javascript 复制代码
Promise.resolve().then(() => {
    // 复杂计算逻辑
})

🌟 Promise.reject

与Promise.resolve类似

🌟🌟 Promise.all

将多个promise实例封装成一个promise

🌟🌟 Promise.race

Promise.race的妙用。这个在我的业务代码中也用到了这个小技巧。

参考资料

阮一峰ES6教程:es6.ruanyifeng.com/#docs/promi...

杰哥课堂:www.bilibili.com/video/BV145...

相关推荐
GISer_Jing43 分钟前
WebGL跨端兼容实战:移动端适配全攻略
前端·aigc·webgl
迦南giser1 小时前
前端性能——传输优化
前端
小白_ysf1 小时前
Vue 中常见的加密方法(对称、非对称、杂凑算法)
前端·vue.js·算法
2501_944448002 小时前
Flutter for OpenHarmony衣橱管家App实战:支持我们功能实现
android·javascript·flutter
人工智能训练7 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪8 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9229 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233229 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头882111 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas13611 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js