day_32 回调地狱和promise对象

一、同步异步

1.同步(阻塞):代码按照顺序依次执行

2.异步(非阻塞):代码不会按照正常的顺序执行

多数情况下,如要在异步之后执行各种逻辑 

  function ajax(cb){ // callback --->回调函数
            setTimeout(()=>{
                console.log("ajax执行完毕");
                cb && cb(); // 短路运算符
                // if(cb){
                //     cb();
                // }
                // cb()
            })
        }
  // 回调地狱:回调函数出现层层嵌套:1.写法不优雅 2.不便于维护
        ajax(function(){
            console.log("执行了111");
            ajax(function(){
                console.log("执行了222");
                ajax(function(){
                    console.log("执行了333");
                })
            })
        })

typeof方法 

        // let a ;
        let a = 10;
    
        // 这种判断a是否定义的方式更加安全
        if(typeof a !="undefined"){
            console.log(a);
        }else{
            console.log("a未定义");
        }

二、回调地狱之小方块运动

  // 让方块从左至右运动 
    function move(ele,target,dir,cb){
        let timer = setInterval(function(){
            let leftNum = parseInt(getComputedStyle(ele,null)[dir]);
            // console.log(leftNum);
            let speed = 5*(target>leftNum?1:-1);
            leftNum += speed;
            ele.style[dir] = leftNum + "px";
            if(leftNum == target){
                // 运动停止
                clearInterval(timer);
                cb && cb();
            }

        },10)
    }

    let boxEle = document.querySelector(".box");

    // 回调地狱:解决异步通过回调,解决回调地狱 ?ES6出现一个 promise
    move(boxEle,300,"left",function(){
        console.log("右边停止了");
        move(boxEle,300,"top",function(){
            console.log("下边停止了");
            move(boxEle,300,"left",function(){
                console.log("左边结束了");
                move(boxEle,0,"top",function(){
                    console.log("上边结束了");
                })
            })
        })
    })

三、认识promise

Promise:承诺,预定义的一个类

一、promise对象的三种状态

        1.实例化一个promise对象 [[PromiseState]]:"pending"(等待)

        let p = new Promise(()=>{

        })

        console.log(p);

         2.实例化一个promise对象,当调取一个参数的时候,状态会变成

[[PromiseState]]:"fulfilled"(resolved)状态

        let p = new Promise((resolve,reject)=>{
            resolve("hello"); // 调取resolve 那么promise对象的状态就会改变 fulfilled状态
            如果给resolve传参 那么状态的[[PromiseResult]]的值就是传递的参数
        })

        console.log(p);

         3.实例化一个promise对象,当调用reject的时候,那么PromiseState会变成

rejected状态

 let p = new Promise((resolve,reject)=>{       

            reject("error"); // 如果给reject传参数,那么参数会是promise对象的[[PromiseResult]]的值
        })
        console.log(p);

 二、每个promise对象都会有一个then方法:then会有2种回调函

数; 1.onResolved 2.onRejected; 

        let p = new Promise((res,rej)=>{
            // res("hello");
            rej("error");   
        })
        p.then(function(res){ //这个位置接收的参数是promise对象的结果值  PromiseResult的值
            // onResolved:当promise对象是一个fulfilled(resloved)状态的时候会执行第一个回调
            console.log("onResolved",res);
        },function(err){
            //onRejected:当一个promise对象是一个rejected状态的时候会执行这个回调函数
            console.log("onRejected",err);
        })

三、如何处理异步问题

        function ajax(cb){
            setTimeout(()=>{
                console.log("ajax获取完毕");
                cb();
            },1000)
        }
        ajax(function(){
            console.log("ajax执行完了");
        })

通过promise来改造异步问题

        function ajax(){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    // console.log("ajax获取完毕");
                    resolve("ajax获取完毕");
                },1000)
            })
        }
        ajax().then(function(res){
            console.log(res);
            console.log("ajax执行之后执行的代码");
        }) // 得到一个promise对象

 四、then的三种返还值

       let p = new Promise((resolve)=>{
                resolve("success");
            })

 1.如果then的回调不返还任何内容,会返还一个promise对象

         let res = p.then(function(res){
                console.log("成功",res);
            })

            console.log(res); 

 2.如果返还普通内容,会把普通的值包装成一个promise对象,然后再返还

    let res = p.then(function(res){
                return 111;
            })
            console.log(res);

 3.如果返还一个promise对象:then会自动把原来的promise返还

    let res = p.then(function(res){
                return new Promise(resolve=>{
                    resolve("返还的promise对象");
                })
            })
            console.log(res);

  总结:无论如何.promise的then方法都会得到一个promise对象;(每个promise

对象都会有一个then方法)

        then可以无限链式调用

  let p = new Promise(res=>{
                res(111);
            })

            let p2 = p.then(res=>{
                console.log(res); // 111
                return new Promise(res=>{
                    res(222);
                })
            })

            let p3 = p2.then(res=>{
                console.log(res); // 222
                return 333;
            })

            p3.then(res=>{
                console.log(res); // 333
            })

 五、回调地狱的解决

    function ajax(cb){
                setTimeout(()=>{
                    console.log("ajax获取完毕");
                    cb();
                },1000)
            }
            // 回调地狱
            ajax(function(){
                console.log("ajax执行完了111");
                ajax(function(){
                    console.log("ajax执行完了222");
                    ajax(function(){
                        console.log("ajax执行完了333");
                    })
                })
            })

            function ajax(){
                return new Promise((resolve,reject)=>{
                    setTimeout(()=>{
                        // console.log("ajax获取完毕");
                        resolve("ajax获取完毕");
                    },1000)
                })
            }

            // 通过变量接收的promise对象
        //    let p2 = ajax().then(function(res){
        //        console.log(res);
        //        console.log("ajax执行之后执行的代码111");
        //        return ajax();
        //     })

        //     let p3 = p2.then(res=>{
        //         console.log("ajax执行之后执行的代码222"); // 222
        //         return ajax();
        //     })

        //     p3.then(res=>{
        //         console.log("ajax执行之后执行的代码333"); // 333
        //     })

        // 直接书写,链式操作;
            ajax().then(function(res){
                console.log(res);
                console.log("ajax执行之后执行的代码111");
                return ajax();
            }).then(res=>{
                console.log("ajax执行之后执行的代码222");
                return ajax();
            }).then(res=>{
                console.log("ajax执行之后执行的代码33343");
            })

四、promise认识2

  // 一、回调的预加载 实现
        // 加载一张图片 然后绘制在canvas上
        // 1.加载图片
        // function loadImg(src,cb){
        //     let img = new Image();
        //     img.src = src ; 
        //     img.onload = function(){
        //         // 证明 图片加载完毕 且是一个异步过程
        //         cb && cb(this); // 调取cb的同时 会把已经加载好的图片对象传入到回调函数里
        //     }
        // }

        // // 2.绘制图片到canvas画布上 
        // let imgUrl = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F1115%2F0ZR1095111%2F210ZP95111-10-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1645059929&t=6e7617e3a50ded2365ac6a10707e4b49";

        // let canvas = document.querySelector("#mycanvas");
        // let ctx = canvas.getContext("2d");
        // loadImg(imgUrl,function(img){
        //     console.log(img);
        //     ctx.drawImage(img,0,0);
        // })
 // 二、做promise改造
        function loadImg(src){
            return new Promise((resolve,reject)=>{
                let img = new Image();
                img.src = src;
                img.onload = function(){
                    // 证明图片加载完毕 且是一个异步过程
                    // cb && cb(this); // 调取cb的同时 会把已经加载好的图片对象传入到回调函数里 
                    resolve(this);
                }
                img.onerror = function(){
                     reject("图片加载失败");
                }
            })
        }

        // 2.绘制图片到canvas画布上 
        let imgUrl = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F1115%2F0ZR1095111%2F210ZP95111-10-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1645059929&t=6e7617e3a50ded2365ac6a10707e4b49";
        // let imgUrl = "https://gimg2.baidu";
        let canvas = document.querySelector("#mycanvas");
        let ctx = canvas.getContext("2d");
        // loadImg(imgUrl,function(img){
        //     console.log(img); // 可以使用已经加载好的图片了
        //     ctx.drawImage(img,0,0);
        // })
        loadImg(imgUrl).then(res=>{
            console.log("图片加载成功",res);
            ctx.drawImage(res,0,0);
        },err=>{
            console.log("图片加载失败",err);
        })

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值