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...

相关推荐
晚烛1 小时前
CANN + 物理信息神经网络(PINNs):求解偏微分方程的新范式
javascript·人工智能·flutter·html·零售
saber_andlibert1 小时前
TCMalloc底层实现
java·前端·网络
逍遥德1 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
冻感糕人~2 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
程序员agions2 小时前
2026年,“配置工程师“终于死绝了
前端·程序人生
alice--小文子2 小时前
cursor-mcp工具使用
java·服务器·前端
晚霞的不甘2 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
小迷糊的学习记录2 小时前
0.1 + 0.2 不等于 0.3
前端·javascript·面试
空&白2 小时前
vue暗黑模式
javascript·vue.js
梦帮科技3 小时前
Node.js配置生成器CLI工具开发实战
前端·人工智能·windows·前端框架·node.js·json