Promise和事件的同步异步

发布时间:2023-09-19 14:00

js是一个异步开发语言

什么是异步呢,很好理解,一般的我们的代码执行的顺序是同步的,也就是执行完这条代码再执行下一条代码,而异步就是我们在某个时间点执行某个代码,而不是顺序执行

创建一条我们比较熟的预加载,这里就是一个典型的异步操作
       var set=new Set();
        for(var i=2;i<5;i++){
            var img=new Image();
            img.src=\"./img/\"+i+\"-.jpg\";
            img.addEventListener(\"load\",loadHandler);
        }

        function loadHandler(e){
            set.add(this);
            if(set.size===3){
                console.log(\"全部加载完成\")
            }
        } 


还有一些比较常见的封装好的函数,也是异步擦欧洲哦
         setTimeout();
         setInterval();
         requestAnimationFrame();

         console.log(\"a\");
        for(var j=0;j<1000000000;j++){

        }
        console.log(\"b\"); 

Promise

一般程序员的思维就是不产生异步代码,让代码按顺序执行下去,于是就会出现在一个函数中不断回调我们所需要的代码,这样就会产生回调地狱,回调地狱会让代码一直往下沉,永远跳不除这个地狱中。

典型的回调地狱,因为我想让图片1加载完再加载图片2,然后图片3,45,所以就会不断回调onload事件,这样就会越陷越深,(用函数式编程就会完美地解决这个问题。)
        var img=new Image();
        img.src=\"./img/2-.jpg\";
        img.onload=function(){
            var img1=new Image();
            img1.src=\"./img/3-.jpg\";
            img1.onload=function(){
                var img2=new Image();
                img2.src=\"./img/4-.jpg\";
                img2.onload=function(){
                    console.log(\"a\");
                  
                }
            }
        }

promise的出现完美地解决了这个问题,我们即使不用函数式编程也可以让代码异步执行,而不是顺序执行

Promise语法

   var p= new Promise(function(resolve,reject){
        resolve();
    })
    p.then(function(){
        console.log(\"aaa\");
    })



    var p= new Promise(function(resolve,reject){
        reject();
    });
    p.catch(function(){
        console.log(\"bbb\");
    })

promise分别有两个参数resolve,reject
这两个参数又分别可以传入一个参数。(仅一个参数)
当执行reject时,会执行后面的then当中第二个函数,如果有catch()
则会执行catch方法中的函
如果既有then中第二个函数也有catch,则完成then中第二个函数,catch不执行
注意!这两个参数只能选一个执行。


注意!!!
     var p= new Promise(function(resolve,reject){
        reject();
        resolve();
       
        console.log(\"ccc\");
        // 这两个方法只能二选其一执行
    });
    p.then(function(){
        console.log(\"aaa\");
    }).catch(function(){
        console.log(\"bbb\");
    })
    console.log(p);

第二种写法,静态写法
这种写法跟上面的构建函数的写法完全相同,执行的功能也完全相同。

Promise.resolve().then(function(){
})

链式结构
在promise的写法中,then是可以连着写的,也就是我创建的then或者catch可以进行下一层

     链式结构
       loadImage(\"./img/2-.jpg\").then(function(){
          console.log(\"加载完成2-jpg\");
          return loadImage(\"./img/3-.jpg\");
      }).then(function(){
        console.log(\"加载完成3-jpg\");
        return loadImage(\"./img/4-.jpg\");
      }).then(function(){
        console.log(\"加载完成4-jpg\"); 
      }); 

promise的状态

PromiseState=pending 初始值
当执行resolve函数时或者reject函数时,首先判断PromiseState是不是pending,
如果是pending, 则运行掉用then中函数或者catch的函数
 如果不是pending,就不执行后面的函数
如果执行resolve后就会被标记为fulfilled
如果执行reject后就会被标记为rejected
    fulfilled   resolve执行状态
    rejected    reject执行状态
    pending  起始状态,挂起状态

promise的不同的三种状态,可以对应不同 的方法

小练习:用promise完成一个简单的红绿灯案例

    function showLight(light,time){
        if(!time) time=2000;
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log(light)
                resolve();
            },time);
        })
    }

    fns();
    function fns(){
        showLight(\"红灯\").then(function(){
        return showLight(\"黄灯\");
        }).then(function(){
            return showLight(\"绿灯\");
        }).then(function(){
            fns();
        })
    } 

async 和await
async 返回一个Promise对象
await 后面只能等待promise对象resolve或者reject,其他都不行
await必须写在async函数中
async中的return 等同这个Promise的resolve
async中throw等同于这个Promise的reject
但是不管是return或者throw都不可异步返回,只有在使用await后才可以异步返回

async function fns(){
    return 1;//使用return 相当于执行了resolve
    throw \"aaa\";//使用 throw相对于执行了reject

一个小案例就能更好的理解这两个类promise

这里我需要按照a两秒后执行b,三秒后执行c,所以需要用到await
     async function fns(){
        console.log(\"a\");
        await waitTime(2000);//阻塞式同步
        console.log(\"b\");
        await waitTime(3000);
        console.log(\"c\");
     }

     function waitTime(time){
        return new Promise(function(resovle){
             setTimeout(function(){
                console.log(time/1000+\"秒执行完成\");
                resovle();
             },time);
        })
     }

同步任务 和 异步任务
这里的任务指的就是事件
异步任务分为两种:微任务和宏任务
宏任务 setTimeout setInterval
微任务 Promise
先执行同步任务,遇到微任务时,将其放在当前任务列的最底端,
遇到宏任务则会开辟一个新任务列,并且放在任务列的最顶端

这里我们需要清楚任务的执行顺序和创建顺序,先缕清执行顺序,然后在理解创建顺序,这里经常出现面试题

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号