认识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中的异步编程问题,避免回调地狱,使代码更加清晰和易于维护

相关推荐
pobu16818 分钟前
aksk前端签名实现
java·前端·javascript
0wioiw029 分钟前
Flutter基础(前端教程⑤-组件重叠)
开发语言·前端·javascript
冰天糖葫芦41 分钟前
VUE实现数字翻牌效果
前端·javascript·vue.js
Brilliant Nemo44 分钟前
集成CommitLInt+ESLint+Prettier+StyleLint+LintStaged
javascript
嘉琪0011 小时前
2025 js——面试题(7)——ajax相关
开发语言·javascript·ajax
liu_yueyang1 小时前
JavaScript VMP (Virtual Machine Protection) 分析与调试
开发语言·javascript·ecmascript
huihuihuanhuan.xin2 小时前
前端八股-promise
前端·javascript
西瓜_号码2 小时前
React中Redux基础和路由介绍
javascript·react.js·ecmascript
A了LONE3 小时前
h5的底部导航栏模板
java·前端·javascript
轻语呢喃3 小时前
JavaScript :事件循环机制的深度解析
javascript·后端