• 【Promise】一文带你了解promise并解决回调地狱


    Promise

    为什么需要promise

    需求

    通过ajax请求id,再根据id请求用户名,再根据用户名获取email

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="./jquery-3.6.0.js">script>
    head>
    <body>
        <script>
            //通过ajax请求拿到用户id
            $.ajax({
                type:"GET",
                url:"./data1.json",
                success:function(res){
                    let {id} = res;
                    console.log(id);
    
                    //通过用户id找到用户名
                    $.ajax({
                        type:"get",
                        url:'./data2.json',
                        data:{id},
                        success:function(res){
                            let {username} = res;
                            console.log(username);
    
                            //通过用户名找到用户邮箱
                            $.ajax({
                                type:"GET",
                                url:"./data3.json",
                                data:{username},
                                success:function(res){
                                    let {email} = res;
                                    console.log(email);
                                }
                            })
                        }
                    })
                }
            })
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    回调地狱

    在回调函数中嵌套回调
    在上述代码中通过不断请求数据,代码逐级向外递归,形成了回调地狱。
    使用promise就可以完美解决,并且让我们的代码更加美观。

    Promise的基本使用

    Promise是一个构造函数,通过new关键字实例化对象.
    语法:

    new promise((reso1ve,reject)=>{})
    
    • 1

    Promise接受一个函数作为参数
    在参数函数中接受两个参数

    • resolve:
    • reject:

    promise实例

    promise实例有两个属性:

    • state:状态
    • result:结果
      在这里插入图片描述

    promise的状态

    1. pending(准备,待解决,进行中)
    2. fulfilled(已完成,成功)
    3. rejected(已拒绝,失败)

    promise状态的改变

    通过调用resolve和reject改变当前promise对象的状态。

    • 改为fulfilled
    let p = new Promise((resolve,reject)=>{
    	resolve(); //调用resolve将状态改为fulfilled
    	});
    console.log(p)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    • 改为rejected
    let p = new Promise((resolve,reject)=>{
         reject();//调用reject将状态改为rejected
       	 });
    console.log(p)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    注意:promise状态的改变是一次性的,即不能同时调用resolve和reject,若同时调用则状态只改变一次。

    promise的结果

    promise的结果是通过传递resolve/reject的参数来获得的

    let p = new Promise((resolve,reject)=>{
             resolve("成功")
         })
    console.log(p);
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    同理,reject也是如此:

    promise方法

    then方法

    then方法中有两个参数,且都为函数作为参数。
    如:

    let p = new Promise((resolve,reject)=>{
        resolve("成功")
        })
    p.then(()=>{
        console.log('成功时执行');
    },()=>{
        console.log("失败时执行");
    })
    console.log(p);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 第一个函数参数
      当promise的状态为fulfilled时,执行该函数
    • 第二个函数参数
      当promise的状态为rejected时,执行该函数

    在这里插入图片描述

    通过then方法获取promise的结果

    通过then方法中的函数传递形参即可获得promise的结果;

    let p = new Promise((resolve,reject)=>{
        resolve("成功")
    })
    p.then((value)=>{
        console.log('成功时执行',value);
    },(reason)=>{
        console.log("失败时执行",reason);
    })
    console.log(p);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    总结:promise的状态用来判断then方法执行成功或是失败的函数,promise的结果则是作为实参传递给then方法的函数参数的形参。

    then方法的返回值

    then方法返回的为一个新的promise对象。且该promise对象的状态为pending,then方法为一个同步操作,then中的函数参数为异步操作。

    在这里插入图片描述
    如上图我们就可以看到then方法的返回值仍然为一个promise对象,且在刚生成该对象时的状态为pending。

    由此衍生出了链式操作:

    new Promise(()=>{}).then().then()
    
    • 1

    在该操作中,如果promise对象的状态不改变则不会执行then方法中的函数。那么在then方法返回的promise对象中如何让其状态改变呢??

    1. 使用return可以将then方法返回的promise对象状态改为fulfilled。
    2. 在then方法中书写错误代码,即可将其promise对象状态改为rejected

    实例:

    let p = new Promise((res,rej)=>{
    	res('苏凉');
    })
    
    let t = p.then((value)=>{
        return "name:"+value;
    },(reason)=>{
        console.log("执行失败!");
    })
    
    t.then((value)=>{
        console.log(value);
    },(reason)=>{
        console.log(reason);
    })
    console.log(t);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    catch方法

    catch方法在promise对象的状态为rejected时亦或者是输入错误代码时被调用,并返回错误原因。

    let p = new Promise((res,rej)=>{
        throw newError("出错啦!")
    })
    p.catch((reason)=>{
        console.log(reason);
    })
    console.log(p);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    解决回调地狱

    //封装Ajax请求函数
    function getAjax(path,data){
       return new Promise((resolve,reject)=>{
            $.ajax({
                type:'get',
                url:path,
                data:{data},
                success:function(res){
                    resolve(res)
                },
                error:function(res){
                    reject(res)
                }
            })
        })
    }
    
    getAjax('./data1.json')
    .then((value)=>{
        let id = {value};
        return getAjax("./data2.json",id)
    })
    .then((value)=>{
        let {username} = value;
        return getAjax('./data3.json',username)
    })
    .then((value)=>{
        console.log(value);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述

  • 相关阅读:
    百炼成钢 —— 声网实时网络的自动运维丨Dev for Dev 专栏
    GitHub Copilot 自动写代码插件使用体验
    《Playing repeated games with Large Language Models》全文翻译
    【无标题】
    Python图像处理丨带你掌握图像几何变换
    超级强大的菜鸟工具库
    微信,支付宝在线换钱平台系统源码
    K8s 场景下 Logtail 组件可观测方案升级-Logtail 事件监控发布
    湖南湘菜 7页面 美食主题 带设计说明 美食网页设计制作 HTML美食网页成品 美食网页成品 HTML美食网页设计
    WPF——样式与模板
  • 原文地址:https://blog.csdn.net/weixin_46277553/article/details/126485145