深入浅出promise、await和async以及Generator系列——promise的由来

前言

  • 在前端的面试中会经常遇到promise相关的问题,其实面试官关注的就是对于promise的使用和理解,本篇文章就从为什么需要promise以及promise相关的内容介绍promise。

promise的由来

  • 众所周知,promise的使用离不开异步的问题,要把promise理解透彻最重要就是要理解什么是异步,为什么promise和异步是紧密结合在一起的

  • 异步

    • 关于异步和同步的介绍大家可以参考我写过的event loop这篇文章,里面详细介绍了哪些是异步,以及异步执行的原理,本篇文章不再对异步详细介绍,只做大致的解释
    • 异步我们可以理解这段代码不会立即执行,会在所有的同步代码之后执行,接下来就用ajax封装的案例来演示
  • 封装同步的ajax

    • 同步的ajax我们可以使用返回值的方式得到后端返回的数据
        function ajax(type, url, data){
            // 1. 创建一个实例
            var xhr = new XMLHttpRequest()
            // 2. 配置请求信息
            // 判断请求方式是get还是post
            if(type === 'get'){
                // false代表同步请求
                xhr.open(type, url+data, false)
                // 3. 发出请求
                xhr.send()
            }else{
                xhr.open(type,url,false)
                // 设置请求头 规定前端发给后端的数据格式
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                // 3. 发出请求
                xhr.send(data.slice(1))
            }
            // 4. 返回后端响应的数据
            return xhr.responseText    
        }
    
        // 使用
        var result = ajax(
            "get",
            "./serve/get.php",
            "?username=jack&password=123456"
        );
        // 直接得到返回值结果
        console.log(result);
    
  • 封装异步的ajax

    • 异步的ajax无法通过返回值的方式返回后端的数据,必须需要监听等待ajax的数据返回才能够直接返回
    • 这时候返回值就不能达到目的了,我们需要借助回调函数来实现接收ajax的结果
        function ajax(type, url, data, cb){
            // 1. 创建一个实例
            var xhr = new XMLHttpRequest()
            // 2. 配置请求信息
            // 判断请求方式是get还是post
            if(type === 'get'){
                xhr.open(type, url+data, true)
                // 3. 发出请求
                xhr.send()
            }else{
                xhr.open(type,url,true)
                // 设置请求头 规定前端发给后端的数据格式
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                // 3. 发出请求
                xhr.send(data.slice(1))
            }
            // 4. 返回后端响应的数据
            xhr.onload = function(){
                cb(xhr.responseText)
            }
        }
    
        // 使用 利用回调函数获取后端返回的数据
        ajax(
            "get",
            "./serve/get.php",
            "?username=jack&password=123456",
            function(res){
                console.log(res)
            }
        );
    
  • 回调函数的问题

    • 当我们多个请求有一定的顺序关系时候,这时候就会导致回调函数嵌套的问题,如果嵌套层级过深,就会出现传说的回调地狱问题,比如
        ajax(
            "get",
            "./serve/a.php",
            "?username=jack&password=123456",
            function(res){
                console.log(res)
                ajax(
                    "get",
                    "./serve/b.php",
                    `?data=${res}`,
                    function(res){
                        console.log(res)
                        ajax(
                            "get",
                            "./serve/c.php",
                            `?data=${res}`,
                            function(res){
                                console.log(res)
                                ajax(
                                    "get",
                                    "./serve/d.php",
                                    `?data=${res}`,
                                    function(res){
                                        console.log(res)
                                    }
                                );
                            }
                        );
                    }
                );
            }
        );
    
  • 解决回调地狱问题的途径就需要用到新的语法,这时候es6就提出了promise

posted @ 2022-08-30 16:58  Mjser  阅读(45)  评论(0编辑  收藏  举报