认识Promise

Promise

回调地狱

在回答这个问题之前,我们先来聊一聊回调地狱,我们都知道Promise是用来解决回调地狱的,那么什么是回调地狱呢?我先用一个简单的例子说明一下 比如你正在马路等红绿灯,那么红绿灯的顺序一定是红灯-黄灯-绿灯,在代码中可以这样表示

javascript 复制代码
setTimeout(() => {
    console.log("红灯");
    setTimeout(() => {
        console.log("黄灯");
        setTimeout(() => {
            console.log("绿灯");
        },1000)
    },1000)
},1000)

上面的段代码就是对回调地狱的一个简单描述,当后一个行动需要等待上一个结果时,会一层一层的嵌套下去,这只是一个简单的描述,想象一下,如果上面这段代码丰富起来会变成什么样,比如红灯的时候马路的车会停下来,人会在斑马线等待...,或者绿灯之后还能继续嵌套,这样的代码可读性会变得非常差,所以这个时候Promise应运而生

Promise的描述

在说这个之前先感谢袁进老师的讲解,这里附上链接 www.bilibili.com/video/BV1qu...

promise有两套规范,一个是es6之前跟es6之后的,我们先来说es6之前的 在es6之前Promise是一个社区规范,叫做Promise A+,A+规范说明了Promise就是一个带then方法的对象或者函数,并且Promise之间可以互相通信 到了es6之后官方吸收了这些民间标准,并新增了一些方法,更新了一个构造函数--new Promise(),我们通过这个构造函数创建的实例化对象来满足Promise规范 总的来说es6之前Promise A+就是一个带then方法的对象或者函数,在es6后,它是一个构造函数,通过它创建的实例满足了Promise A+规范,只要满足了Promise A+规范,它们之间就可以互相操作,还可以使用es7中的async跟await

Promise的用法

创建Promise

使用new Promise(executor)的构造函数创建,这里的executor是一个函数,他有两个形参resolve和reject,executor函数内部执行异步操作,成功调用resolve,失败调用reject

javascript 复制代码
//创建Promise实例
let p=new Promise(function(resolve,reject){
    let flag=true;
    if(flag){//假设异步操作成功
        resolve("成功");//此时Promise状态从pending变为fulfilled,并将结果传递出去
    } else {
        reject("失败")//将Promise状态从pending变成rejected,并将错误信息传递出去
    }
})

Promise的状态

Promise的核心是一个状态机,一共有三种状态:

  • Pending(等待)
  • Fulfilled(完成)
  • Rejected(拒绝)

状态一旦改变就不能再变:

  • Pending -> Fulfilled
  • Pending -> Rejected

使用Promise

通过.then()、.catch()、finally()方法处理结果或者错误

then(onFulfilled,onRejected)

then方法内部接收两个函数

  • 当Promise状态变为 已完成(fulfilled) 时,调用onFulfilled函数,这个函数会接收resolve传递过来的值作为参数
  • 当Promise状态变为 已拒绝(rejected) 时,调用onRejected函数,这个函数会接收reject传递过来的值作为参数
javascript 复制代码
p.then(function (res){
    //处理成功
    console.log(res);
}, function (err){
    //处理失败
    console.log(err);
})
catch(onRejected)

catch方法是ES6规范中新增的,在Promise A+规范中并没有规定。它相当于.then(null, onRejected),专门用于处理失败状态。推荐使用.catch()来处理错误,因为它可以捕获前面所有.then()方法中的错误,并且更接近同步的try/catch代码风格。

javascript 复制代码
p.then(function (res) {
    //处理成功
    console.log(res);
}).catch(function (err) {
    //处理失败
    console.log(err);
})
finally(onFinally)

无论Promise最终状态是成功还是失败,都会执行onFinally函数

javascript 复制代码
p.finally(function() {
  console.log("无论成功或失败,都会执行");
});

Promise解决回调地狱

还是以上面红绿灯为例

javascript 复制代码
function light(time, color) {
    //这里只模拟成功状态,time用来模拟现实中的网络请求快慢
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(color)
        }, time)
    })
}

light(1000, "红灯")
    .then(function (res) {
        console.log(res);
        return light(1000, "黄灯");// 返回新Promise
        // 只有上面返回的light函数状态变为已完成(fulfilled)才会执行下面的.then()方法
    }).then(function (res) {
        console.log(res);
        return light(1000, "绿灯");
    }).then(function (res) {
        console.log(res);
    })

这样代码就会变成链式调用,避免了层层嵌套,提高了可读性

async/await

谈到Promise同样离不开async跟await,它是es7引入的语法糖,是解决回调地狱的终极方案,可以使异步代码看起来像同步代码 async用来修饰一个函数,被修饰的函数默认返回值不再是undefined,而是会返回一个Promise await只能在async修饰的函数内部使用,它会暂停await下面的代码执行,等待Promise完成 将我们上面封装的函数加上async跟await:

ini 复制代码
async function trafficLight() {
    let light1 = await light(1000, "红灯");
    console.log(light1);
    let light2 = await light(1000, "黄灯");
    console.log(light2);
    let light3 = await light(1000, "绿灯");
    console.log(light3);
}
trafficLight();

通过Promise和async/await,我们可以优雅地解决JavaScript中的异步编程问题,避免回调地狱,使代码更加清晰和易于维护

相关推荐
西岭千秋雪_2 分钟前
前端工程化:npm&vite
前端·javascript·npm·node.js
BUG收容所所长12 分钟前
HoverMask与SelectedMask——如何让低代码平台的交互体验更加直观?
前端·javascript·设计
Mintopia28 分钟前
🌐AIGC:从硅芯片中孕育的缪斯女神
前端·javascript·aigc
掘金安东尼32 分钟前
⏰前端周刊第425期(2025年7月28日–8月3日)
前端·javascript·面试
namehu33 分钟前
为什么我的margin-top被转换为vw而不是vh?
javascript·css·postcss
雪中何以赠君别34 分钟前
Vite + Axios + Nginx 环境变量与代理配置笔记
前端·javascript·vue.js
icebreaker37 分钟前
weapp-tailwindcss 已支持 uni-app x 多端构建
前端·javascript·uni-app
超龄超能程序猿37 分钟前
玩转 Playwright 有头与无头模式:消除差异,提升爬虫稳定性
前端·javascript·爬虫
PineappleCoder1 小时前
用 “私房钱” 类比闭包:为啥它能访问外部变量?
前端·javascript·面试
Mintopia1 小时前
🧠 Next.js 是什么?它为什么像是 Web 世界的“九转大还丹”
前端·javascript·next.js