• 11-利用Promise的图片异步加载 / Promise封装ajax,模拟axios / Promise的finally原理


    Promise的图片异步加载其实就是利用了宏任务先执行,后执行微任务:

    new Promise()的时候,Promise新建后就会立即执行

     利用这一特性,我们可以创建Promise对象的时候,创建image标签,然后再给img标签的 src赋值路径,这样在then的回调函数中,把其加入到盛放显示图片的盒子中,盒子中原来展示是一个缺省图,等到图片加载好了,就显示真正的图片:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5     <meta charset="UTF-8">
     6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     8     <title>Document</title>
     9 </head>
    10 <style>
    11     h1 {
    12         display: block;
    13     }
    14 </style>
    15 
    16 <body>
    17     <div id='box'>
    18         <h1>我是一张缺省图</h1>
    19     </div>
    20 </body>
    21 
    22 </html>
    23 <style>
    24 
    25 </style>
    26 <script>
    27     var oBox = document.getElementById('box');
    28     var oH = document.querySelector('h1')
    29 
    30     function loadImageAsync(url) {
    31         return new Promise(function(resolve, reject) {
    32             var image = new Image();
    33 
    34             image.onload = function() {
    35                 resolve(image);
    36             };
    37 
    38             image.onerror = function() {
    39                 reject(new Error('Could not load image at ' + url));
    40             };
    41 
    42             image.src = url;
    43         });
    44     }
    45     // 模拟一下异步加载图片
    46     // 用setTimeoutm模拟ajax调用接口,获取接口返回的图片路径,然后传入函数中,函数中已经提前创建好了
    47     // 图片标签。我们在.then的回调函数中自行决定插入div容器中做一些事,比如把缺省图隐藏掉
    48     setTimeout(() => {
    49         loadImageAsync('./lion.jpg').then(res => {
    50             oH.style.display = 'none';
    51             oBox.appendChild(res);
    52         })
    53     }, 1000)
    54 </script>

     1秒后显示图片:


     Promise封装ajax

     1    function myAxios(url) {
     2         return new Promise((resolve, reject) => {
     3             let http = new XMLHttpRequest();
     4             http.open('GET', url)
     5             http.onreadystatechange = function() {
     6                 if (this.readyState !== 4) {
     7                     return
     8                 }
     9                 if (this.status === 200) {
    10                     resolve(this.response)
    11                 } else {
    12                     reject(new Error(this.txt))
    13                 }
    14             }
    15             http.send();
    16         })
    17     }
    18 
    19     myAxios('').then(res => {
    20         // 拿到数据
    21     }).catch(err => {
    22         // 捕获错误
    23     })

    Promise的finally原理

     finally中的函数无参数的情况:

      Promise.prototype.Myfinally = function(callback) {
            let P = this.constructor;
            return this.then(
                // 正常情况
                () => P.resolve(callback()),
                () => P.resolve(callback())
            );
        };
    
        function promiseFn(flag) {
            return new Promise((resolve, reject) => {
                if (flag) {
                    resolve('正确')
                } else {
                    reject('错误')
                }
            })
        }
        promiseFn(false).then(res => {
            console.log(res, '我是success');
        }).catch(err => {
            console.log(err, "我是err");
        }).Myfinally(res => {
            // console.log(res, '结果'); //不传参,这里就没有res,输出undefined
            console.log('我是finally');
        })

    有参数的情况,直接把成功时或者失败时候的参数传给finally的回调函数,这样一个finally中的那一个参数,既可以捕获到失败也可以捕获到成功

      Promise.prototype.Myfinally2 = function(callback) {
            let P = this.constructor;
            return this.then(
                // 传参的情况
                value => P.resolve(callback(value)),
                reason => P.resolve(callback(reason))
            );
        };
    
        function promiseFn2(flag) {
            return new Promise((resolve, reject) => {
                if (flag) {
                    resolve('正确')
                } else {
                    reject('错误')
                }
            })
        }
        // 传参就可以用finally方法,finally里面的参数是res,也可以是err
        promiseFn2(true).Myfinally2((res) => {
            // res可以是原有的then成功的结果,又可以是catch失败的结果
            console.log(res, '我是结果');
        })
  • 相关阅读:
    fedora 安装open office
    git rebase(转)
    javascript typeof
    正则表达式入门
    XML格式
    zz 通用线程:Awk 实例,第 3部分
    ELF BIN HEX
    i2c总线(iic总线/ I square C)
    grep
    把Nginx注册成Windows 系统服务(转载)
  • 原文地址:https://www.cnblogs.com/haoqiyouyu/p/14716425.html
Copyright © 2020-2023  润新知