• Promise 解决阻塞式同步,将异步变为同步


    一、样式

     var p = new Promise(function(reslove,reject){
         reslove()//在构造的时候就执行这个函数了
     });
     p.then(function(){
    
     }).catch(function(){
         
     })
    ————————————————————————————————————————————————————————————————————————————————————
    new Promise(function(resolve,reject){
        resolve();
    }).then(function(){
        // resolve时执行
    },function(){
        // reject时执行
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • Promise需要实例化完成创建一个Promise对象
    • Promise实例化的构造函数中传入一个回调函数
    • 回调函数中有两个参数,一个是resolve,一个是reject
    • 当成功后调用resolve函数,失败后调用reject函数
    • 并且可以通过resolve或者reject函数传递一个参数
    • Promise实例化的对象执行两个方法一个是then,一个 是catch
    • 这两个方法中有两个回调函数,当执行resolve 时,调用then中回调函数,当执行reject时调用catch 中的回调函数
    • 在Promise实例化的构造中只能调用一次resolve或者一次 reject,调用一次后,再次调用任何一个resolve或者reject都是无效的

    顺序输出异步abc

    new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve()
        },1000)
    }).then(function(){
        console.log('a');
        return new Promise(function(resolve,reject){
            setTimeout(function(){
            resolve()
            },500)
        })
    }).then(function(){
        console.log('b');
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve()
            },1000)
        })
    }).then(function(){
        console.log('c');
    })
    输出:
    a
    b
    c
    
    • 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

    顺序输出异步红绿灯

    function setTime(time){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve()
            },time)
        })
    }
    setTime(100).then(function(){
        console.log('黄灯');
        return setTime(1000)
    }).then(function(){
        console.log('绿灯');
        return setTime(500)
    }).then(function(){
        console.log('红灯');
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    封装返回一个Promise对象

    //次函数返回一个Promise对象
    function setTime(time){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve();
            },time);
        })
    }
    Promise对象执行方法then
    setTime().then(function(){
        console.log('aaa');
    })
    //aaa
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    连缀使用Promise

    function setTime(time){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve();
            },time);
        })
    }
    setTime(500).then(function(){
        console.log('aaa');
        return setTime(1000);
    }).then(function(){
        console.log('bbb');
        return setTime(100);
    }).then(function(){
        console.log('ccc');
    })
    
    aaa
    bbb
    ccc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    预加载图片

    让异步变成一个阻塞式同步

    function loadImage(src){
        return new Promise(function(resolve,reject){
            var img = new Image();
            img.src = src;
            /* 加载完成时执行一下代码 */
            img.onload = function(){
                /* 执行resolve回调函数,传入参数img对象 */
                resolve(img)
            }
        })
    }
    var arr = [];
    /* Promise对象构造的时候执行了回调函数resolve,而执行resolve会调用方法then中的回调函数 */
    loadImage("./img/img_15.JPG").then(img =>{
        arr.push(img)
        return loadImage("./img/img_16.JPG")
    }).then(img =>{
        arr.push(img)
        return loadImage("./img/img_17.JPG")
    }).then(img =>{
        arr.push(img)
        console.log(arr);
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    function loadImage(src){
        return new Promise(function(resolve,reject){
            var img = new Image();
            img.src = src;      
            img.onload = function(){
                resolve(img)
            }
            img.onerror = function(){
                reject(src)
            }
        })
    }
    //错误时执行代码
    var arr = [];
    loadImage("./img/img_11.JPG").then(img =>{
        arr.push(img)
    }).catch(function(src){
        console.error("error:"+src);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    连续then时,相当于自动创建一个return promise并且执行resolve

    new Promise(function(resolve,reject){
       setTimeout(function(){
        resolve();
       },500);
    }).then(function(){
        console.log("aa");
        // 连续then,并没有return新的Promise时,相当于自动return Promise执行了resolve
        // return new Promise(function(resolve,reject){
        //     resolve();
        // })
    }).then(function(){
        console.log("bb");
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    两种快捷写法
    Promise.resolve().then(function(){
    
    })
    Promise.reject().catch(function(){
    
    })      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    图片整体预加载

    • 先把所有异步使用Promise封装后放在一个数组中
    • 然后通过Promise.all传入这个数组,这时候
    • 所有异步执行resolve传入的参数就会被按照
    • 顺序放在一个数组中,并且通过then中参数返回
    function loadImage(src){
        return new Promise(function(resolve,reject){
            var img = new Image();
            img.src = src;
            img.onload = function(){
                resolve(img)
            }
            img.onerror = function(){
                reject(src)
            }
        })
    }
    arr = [];
    for(var i=15;i<19;i++){
        var p = loadImage(`./img/img_${i}.JPG`);
        arr.push(p);
    }
    console.log(arr);
    Promise.all(arr).then(function(list){
        list.forEach(item=>console.log(item));
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    谁先加载完就显示谁

    Promise.race(arr).then(function(img){
    	console.log(img);
    })
    
    • 1
    • 2
    • 3

    最简点的异步加载async,awiat

    function loadImage(src){
        return new Promise(function(resolve,reject){
            var img = new Image();
            img.src = src;
            img.onload = function(){
                resolve(img)
            }
            img.onerror = function(){
                reject(src)
            }
        })
    }
    init();
    async function init(){
        arr = [];
        for(var i=15;i<19;i++){
        	/*自动等待将loadImage函数执行的resolve函数的结果值返回给p*/
            var p = await loadImage(`./img/img_${i}.JPG`);
            arr.push(p);
        }
        console.log(arr);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 异步可以包装成一个promise函数
    • await 只能等待Promise,其他的异步都不能等待
    • 要使用await ,就需要在await所属的函数外使用async
    • 没有async不能单独使用await
    • async函数执行后将会返回一个promise对象
    • async函数中return 结果就相当于promise执行了resolve(return的结果)

    当使用try catch拦截promise中reject时,必须放在async await函数中
    因为这个是异步等待后才报错的

    async function init(){
         try{
           await loadImage("./img/img_14.JPG").then(function(img){
                 console.log(img);
             })
         }catch(e){
             console.log(e)
         }
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    宏任务和微任务

    执行顺序

    同步-->微任务-->微任务中的微任务-->宏任务-->宏任务中的微任务-->微任务中的宏任务-->微任务中的宏任务中的微任务-->宏任务中宏任务
    
    • 1
    new Promise(function (res, rej) {
            // console.log(2);
        })
        .then(function () {
            // console.log(3);
            Promise.resolve().then(function () {
                // console.log(5);
                setTimeout(function () {
                    console.log(6);
                    Promise.resolve().then(function () {
                        console.log(7);
                    });
                    setTimeout(function () {
                        console.log(8);
                    }, 0);
                }, 0);
            });
        })
        .then(function () {
            // console.log(4);
        });
    
    setTimeout(function () {
        // console.log(9);
        new Promise(function (res) {
            res();
            // console.log(10);
        }).then(function () {
            // console.log(11);
        });
    });
    
    Promise.resolve().then(function () {
        setTimeout(function () {
            Promise.resolve().then(function () {
                // console.log(12);
            });
            // console.log(13);
        }, 0);
    });
    
    
    setTimeout(function () {
        setTimeout(function () {
            setTimeout(function () {
                Promise.resolve().then(function () {
                    console.log(14);
                });
                console.log(15);
            }, 0);
            console.log(16);
        }, 0);
        // console.log(17);
    }, 0);
    
    
    // console.log(18);
    
    
    new Promise(function (res) {
        // console.log(19);
        setTimeout(function () {
            // console.log(20);
        }, 0);
    });
    
    
    • 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

    以后看…………………………

    console.log(1);
    document.addEventListener("14", function () {
        console.log(14);
    });
    new Promise(function (resolve) {
        resolve();
        console.log(2);
        setTimeout(function () {
            console.log(3);
        }, 0);
        Promise.resolve().then(function () {
            console.log(4);
            setTimeout(function () {
                console.log(5);
            }, 0);
            setTimeout(function () {
                (async function () {
                    console.log(6);
                    return function () {
                        console.log(7);
                    };
                })().then(function (fn) {
                    console.log(8);
                    fn();
                });
            }, 0);
        });
        new Promise(function (resolve) {
            console.log(9);
            resolve();
        }).then(function () {
            new Promise(function (resolve, reject) {
                    console.log(10);
                    reject();
                })
                .then(function () {
                    setTimeout(function () {
                        console.log(11);
                    }, 0);
                    console.log(12);
                })
                .catch(function () {
                    console.log(13);
                    var evt = new Event("14");
                    document.dispatchEvent(evt);
                });
        });
    });
    setTimeout(function () {
        console.log(15);
        Promise.resolve().then(function () {
            console.log(16);
        });
    }, 0);
    
    • 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
  • 相关阅读:
    【数论】质数
    Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)
    微服务全链路监控中Trace和Span介绍
    Python全栈开发【基础-10】流程控制之for循环
    程序员喜欢Linux系统的原因有哪些?
    罗永浩讽刺iPhone“那么伟大又那么不要脸”;北欧囚犯正在训练AI大模型;ChatGPT治怪病丨RTE开发者日报 Vol.51
    java 问题解决
    丰田+比亚迪「围攻」大众,明年或将「让出」榜首之位
    MobileViT代码分析及添加SE注意力的实验结果
    计算机毕业设计Java大型商场应急预案管理系统(源码+系统+mysql数据库+lw文档)
  • 原文地址:https://blog.csdn.net/m0_46672781/article/details/126147948