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 分钟前
HTML字符串转换为React元素实现
前端·react.js·html
gxn_mmf17 分钟前
典籍知识问答模块AI问答功能feedbackBug修改+添加对话名称修改功能
前端·后端·bug
sunbyte23 分钟前
Three.js + React 实战系列 - 客户评价区细解教程 Clients 组件✨(回答式评价 + 评分星级)
开发语言·javascript·react.js
marvindev34 分钟前
提bug测试专用
开发语言·javascript·bug
samroom1 小时前
Webpack基本用法学习总结
前端·学习·webpack
万能程序员-传康Kk1 小时前
食物数据分析系统vue+flask
前端·vue.js·flask
老猿阿浪2 小时前
JavaScript性能优化:从青铜到王者的进阶之路
开发语言·javascript·性能优化
老华带你飞2 小时前
音乐网站|基于SprinBoot+vue的音乐网站(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·音乐网站
界面开发小八哥3 小时前
DevExtreme JS & ASP.NET Core v25.1新功能预览 - 全新的Stepper组件
javascript·asp.net·界面控件·devexpress·ui开发·devextreme
是程序喵呀3 小时前
uni-app使用web-view组件APP实现返回上一页
前端·uni-app