首页 > 技术文章 > js-promise以及async、await实现简易红绿灯

piaoyi1997 2020-06-15 08:20 原文

一、回调

  1. 回调函数

    • 当一个函数A作为参数,传入另一个函数B中,某种情况下执行,作为参数的函数A,叫回调函数
    • 用处:
      • 获取异步的数据
      • 获取将来的数据
  2. 回调地狱

    • 当回调函数嵌套过多时
      • 格式混乱,不方便程序调试
      • 浪费性能
  3. 回调地狱解决了什么问题

    • 多层异步,嵌套的问题
  4. 更好的解决方式

    • 不产生回调地狱,实现多层异步的需求
      • ES6:Promise
        • 概念
          1. Promise是回调地狱的解决方案之一
          2. 我们使用Promise的语法来解回调地狱
          3. 是代码拥有可读写和维护性
        • 语法

二、Promise

  1. 概念
    • 承诺:分为三个状态:正在进行时,已完成,已失败
    • 完成和失败的状态只允许发生一次且一个
    • promise其实就利用原生js进行的封装
  2. 语法
    • Promise是个构造函数
      • new执行
        • 创建一个实例,实例身上有then方法和catch方法
        let p = new Promise((resolve,reject)=>{
            // 正在进行时....
        
            // 已完成
            resolve();
            // 已失败
            reject();
        })
        
        p.then(()=>{
            // 完成时要做的事情
            // 想做什么做什么
            return 新的promise实例2
        }).then(()=>{
            // 新的promise2的成功处理
            // 想做什么做什么
            return 新的promise实例3
        }).then(()=>{
            // 新的promise3的成功处理
            // 想做什么做什么
            return ......;
        })
        
        p.catch(()=>{
            // 失败时要做的事情
            // 想做什么做什么
            return 新的promise实例2
        }).catch(()=>{
            // 新的promise2的失败处理
            // 想做什么做什么
            return ......;
        })
        
      • 直接作为对象使用
        • Promise.all批量检测
        var p1 = new Promise(...);
        var p2 = new Promise(...);
        var p3 = new Promise(...);
        
        Promise.all([p1,p2,p3]).then((res)=>{
            // 全部成功时,要做的事情
            // res是个数组,内包含所有promise实例的成功之后的数据
        }).catch((res)=>{
            // 只要有一个失败,要做的事情
        })
        
  • 与服务器无关,只是,将来可能会用于解决在服务器环境中的程序中的某些问题

三、async / await

  • ES7提供,专门用于将异步的程序,模拟成同步执行

    • async用来标记一个函数是异步函数
    • await用来将异步的程序同步执行
      • await关键字必须出现在async标记的函数中
      • async的函数中没有await关键字,该怎样就怎样
    • await后需要跟一个Promise实例
    async function fn(){
        let a = await new Promise((success,error)=>{
            success("成功了");
        })
        console.log(a);
    
        let b = await new Promise((success,error)=>{
            error("失败了");
        })
        console.log(b);
    }
    fn();
    

    案例效果如下:

    具体代码如下:

    html代码:
    

    js代码:
    
    var aDiv = document.querySelectorAll('div');
    function active(index,oColor){      
        for(var i = 0;i<aDiv.length;i++){
            aDiv[i].style.background = '';
        }
        aDiv[index].style.background = oColor;
    }  


    var fn = async function(){
            var p1 = await new Promise(function(success,error){
                setTimeout(()=>{
                   success(active(0,'red'));
                },1000)
            });
            var p2 = await new Promise(function(success,error){
                setTimeout(()=>{
                    success(active(1,'green'));
                },1000)       
            });
            var p3 = await new Promise(function(success,error){
                setTimeout(()=>{
                    success(active(2,'yellow'));
                },1000)
            });
            fn();
        }
    fn();    
      ```
- 与服务器无关,只是,将来可能会用于解决在服务器环境中的程序中的某些问题

推荐阅读