• Promise从入门到精通 (第一章 Promise的介绍和基本使用)


    第1章:Promise的介绍和基本使用

    1.1. Promise是什么?

    1.1.1.理解Promise

    1. 抽象表达:

      1. Promise 是一门新的技术(ES6 规范)

      2. Promise 是 JS 中进行异步编程的新解决方案

    备注:旧方案是单纯使用回调函数

    1. 具体表达:

      1. 从语法上来说: Promise 是一个构造函数

      2. 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

    1.2 什么是异步编程?

    1.2.1 同步与异步

    同步:同步是指一个进程在执行某个请求的时候,如果该请求需要一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回信息才继续执行下去。

    异步:异步是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态,当有信息返回的时候会通知进程进行处理,这样就可以提高执行的效率了,即异步是我们发出的一个请求,该请求会在后台自动发出并获取数据,然后对数据进行处理,在此过程中,我们可以继续做其他操作,不管它怎么发出请求,不关心它怎么处理数据。

    1.2.2:同步与异步适用的场景

    就算是ajax去局部请求数据,也不一定都是适合使用异步的,比如应用程序往下执行时以来从服务器请求的数据,那么必须等这个数据返回才行,这时必须使用同步。而发送邮件的时候,采用异步发送就可以了,因为不论花了多长时间,对方能收到就好。总结得来说,就是看需要的请求的数据是否是程序继续执行必须依赖的数据

    1.2.3 异步的常见操作

    • fs 文件操作

      require('fs').readFile('./index.html', (err,data)=>{})
      
      • 1
    • 数据库操作

    • AJAX 请求

        $.get('/server', (data)=>{})
      
      • 1
    • 定时器

      setTimeout(()=>{}, 2000);
      
      • 1

    1.1.2. promise的状态改变

    1. pending 变为 resolved

    2. pending 变为 rejected

    说明: 只有这 2 种, 且一个 promise 对象只能改变一次

    ​ 无论变为成功还是失败, 都会有一个结果数据

    	成功的结果数据一般称为 value, 失败的结果数据一般称为 reason
    
    • 1

    1.3 promise初体验1

    DOCTYPE html>
    <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>
    head>
    
    <body>
        <div class="container">
            <h2 class="page-header">Promiseh2>
            <button class="btn" id="btn">点击抽奖button>
        div>
        <script>
            // 生成随机数
            function rand(m, n) {
                return Math.ceil(Math.random() * (n - m + 1)) + m - 1
            }
    
            // 获取元素对象
            const btn = document.querySelector("#btn");
    
            btn.addEventListener('click', function () {
    
                // 定时器实现
    
                // setTimeout(() => {
                //     if (rand(1, 100) < 30) {
                //         alert("中奖")
                //     } else {
                //         alert("未中奖")
                //     }
                // }, 1000)
                
                /*---------------------------------------------------------------*/
    
                // Promise实现
                /*
                    Promise是一个构造函数(构造函数可通过new进行对象的实例化),promise实例化时要接收一个参数,
                    其参数是函数类型的值,参数中有两个形参,分别是resolve和reject,也是函数类型的数据。
                    Promise内部可包裹异步操作, 如果异步操作成功则调用resolve(),如果失败则调用reject()
                */
                const p = new Promise((resolve, reject) => {
                    setTimeout(() => {
                        if (rand(1, 100) < 30) {
                            resolve(); // 执行后会将promise对象的状态设置为成功
                        } else {
                            reject(); // 执行后会将promise对象的状态设置为失败
                        }
                    }, 1000)
                });
    
                /*
                    then方法 也是Promise实例对象上的方法
                    then方法调用时要传入两个参数,这两个参数都是函数类型的值
                    通过then方法执行成功和失败的回调,参数为两个回调函数,
                    第一个为成功后执行的回调函数,第二个为失败后执行的回调函数
                */
                p.then(() => {
                    alert("中奖了")
                }, () => {
                    alert("没中")
                });
            });
    
    
        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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    1.4 Promise初体验2

    用Promise封装一个异步操作,异步操作成功时调用resolve,并把成功的结果传给resolve,异步操作失败时调用reject,并把失败的原因传给reject。

    在then方法内部可以处理成功或失败后的结果,如果成功则调用第一个回调函数中的代码,如果失败则调用第二个回调函数中的代码。

    DOCTYPE html>
    <html lang="en">
    <body>
        <div class="container">
            <h2 class="page-header">Promiseh2>
            <button class="btn" id="btn">点击抽奖button>
        div>
        <script>
            // 生成随机数
            function rand(m, n) {
                return Math.ceil(Math.random() * (n - m + 1)) + m - 1
            }
            // 获取元素对象
            const btn = document.querySelector("#btn");
            btn.addEventListener('click', function () {
                const p = new Promise((resolve, reject) => {
                    setTimeout(() => {
                        let n = rand(1, 100)
                        if (n < 30) {
                            // Promise除了可以封装异步任务之外还可以获取异步任务成功或失败的结果值
                            // 把n当做结果值,分别传递为resolve和reject函数
                            // 然后在then的回调函数中就可以拿到传递的结果值
                            resolve(n); // 执行后会将promise对象的状态设置为成功
                        } else {
                            reject(n); // 执行后会将promise对象的状态设置为失败
                        }
                    }, 1000)
                });
                /*
                    value:成功返回的结果值
                    reason:失败的理由
                */
                p.then((value) => {
                    alert("中奖了,中奖号码是:"+value)
                }, (reason) => {
                    alert("没中,号码是"+reason)
                });
            });
        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

    1.5 Promise实践练习-fs读取文件

    • 安装express框架 npm install express
    const fs = require('fs');
    // 回调函数形式
    // fs.readFile('D:\a.txt',(err,data)=>{
    //     // 如果有错误,则抛出错误
    //     if(err) throw err;
    //     // 如果没错误,就输出文件内容
    //     console.log(data.toString())
    // })
    
    // Promise形式
    const p = new Promise((resolve, reject)=>{
        fs.readFile('D:\a.txt',(err,data)=>{
            // 如果有错误,则调用reject函数,并把失败原因传入
            if(err) reject(err);
            // 如果没错误,就调用resolve函数,并把成功的结果传进去
            resolve(data);
        })
    })
    
    // 调用then方法,对执行结果进行处理
    p.then(value=>{
        console.log(value.toString())
    },reason=>{
        console.log(reason)
    })
    
    • 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

    1.6 Promis实践练习-AJAX

    目前调用有跨域问题

    DOCTYPE html>
    <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>
    head>
    
    <body>
        <div class="container">
            <h2 class="page-header">Promise 封装AJAX操作h2>
            <button class="btn" id="btn">点击发送AJAXbutton>
        div>
        <script>
            // 接口地址 https://api.apiopen.top/getJoke
            const btn = document.querySelector("#btn");
    
            btn.addEventListener('click', function () {
                
                // 正常编写AJAX流程
    
                // // 1.创建对象
                // const xhr = new XMLHttpRequest();
                // // 2.初始化
                // xhr.open('get', 'https://api.apiopen.top/getJoke');
                // // 3.发送
                // xhr.send();
                // // 4.处理响应结果
                // xhr.onreadystatechange = function(){
                //     if(xhr.readyState === 4){
                //         // 判断响应码
                //         if(xhr.status >= 200 && xhr.status <= 300){
                //             // 控制台输出响应体
                //             console.log(xhr.response)
                //         }else{
                //             // 控制台输出状态码
                //             console.log(xhr.status)
                //         }
                //     }
                // }
    
                // 使用Promise封装AJAX
                const p = new Promise((resolve, reject) => {
                    // 1.创建对象
                    const xhr = new XMLHttpRequest();
                    // 2.初始化
                    xhr.open('GET', 'https://api.apiopen.top/getJoke');
                    // 3.发送
                    xhr.send();
                    // 4.处理响应结果
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState === 4) {
                            // 判断响应码
                            if (xhr.status >= 200 && xhr.status <= 300) {
                                // 请求成功则执行resolve函数
                                resolve(xhr.response)
                            } else {
                                // 请求失败则执行reject函数
                                reject(xhr.status)
                            }
                        }
                    }
                });
                // 调用then方法对请求成功或失败的结果进行处理
                p.then((value)=>{
                    console.log(value);
                },(reason)=>{
                    console.log(reason);
                })
            })
        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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    1.7 Promise封装fs读取文件

    /*
        封装一个函数,mineReadFile 读取文件内容
        参数:path 文件路径
        返回:promise对象
    */
    function minReadFile(path){
        return new Promise((resolve, reject)=>{
            require('fs').readFile(path, (err, data)=>{
                // 判断 如果出现错误,那么就执行reject函数,并把错误信息传入
                if(err) reject(err)
                // 如果没有错误,就执行resolve函数
                resolve(data);
            })
        });
    }
    
    minReadFile("./a.txt").then(value=>{
        console.log(value.toString());
    },reason=>{
        console.log(reason);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.8 使用util.promisify方法进行promise风格化

    /*
        util.promisify 方法 是node中内置的方法  详见:http://nodejs.cn/api/util.html#utilpromisifyoriginal
    */
    
    // 引入util模块
    const util = require('util');
    
    // 引入fs模块
    const fs = require('fs')
    
    // 将fs.readFile传入,并返回一个新的promise风格的函数
    let minReadFile = util.promisify(fs.readFile)
    
    // 使用转换promise风格后的函数
    minReadFile('./a.txt').then(value=>{
        console.log(value.toString())
    }, reason=>{
        
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.9 promise封装AJAX请求

    DOCTYPE html>
    <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>
    head>
    <body>
        <script>
            function sendAJAX(url){
                return new Promise((resolve, reject)=>{
                    const xhr = new XMLHttpRequest();
                    xhr.open("GET",url);
                    xhr.send();
                    // 处理结果
                    xhr.onreadystatechange = function(){
                        if(xhr.readyState === 4){
                            // 判断成功
                            if(xhr.status >= 200 && xhr.status < 300){
                                // 成功的结果
                                resolve(xhr.response);
                            }else{
                                reject(xhr.status);
                            }
                        }
                    }
                });
            }
    
            sendAJAX("http://baidu.com")
            .then(value=>{
                console.log(value);
            }, reason=>{
                console.log(reason);
            })
        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
  • 相关阅读:
    如何理解死锁?
    VLAN中继协议
    java118-vector类
    【瑞吉外卖】day03:完善登录功能与新增员工
    电子学会2023年6月青少年软件编程(图形化)等级考试试卷(三级)真题,含答案解析
    git push 总是需要输入密码或者个人访问令牌personal access token解决方案
    Java中Map架构简介说明
    2023 (ICPC) Jiangxi Provincial Contest -- Official Contest
    Kubernetes(k8s)的三种资源管理方式
    SpringMVC (3)—拦截器
  • 原文地址:https://blog.csdn.net/cjhxydream/article/details/126005474