有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

web前端同步异步高阶-Promise异步处理

javascript cat 3个月前 (07-19) 45次浏览 已收录 0个评论 扫描二维码

最近面试碰到些面试官问Promise说真的,平时用的时候直接写,根本不管他的底层原理,今天没事总结下吧!

同步:代码从上而下依次执行,后面的代码必须要等待前面的代码执行完成之后才能够执行

异步:需要等待才能执行的代码(定时器,事件触发的函数,ajax请求),如果执行代码遇到异步代码,先将异步放到一边,先执行后面的同步代码

ajax异步请求

多个ajax 嵌套请求会形成回调地狱
后期没有办法维护代码
console.log(1);
    //多个ajax 嵌套请求===形成回调地狱
    $http.get('data.json',res=>{

        if(res.id === 42){
            $http.get('data1.json',res1=>{
                //处理js

                if(res1.code == 0){

                    $http.get('data2.json',res2=>{

                        console.log(res2);
                    })
                }
            })
        }

    })

Promise

作用:处理回调地狱的问题

特点:Promise 自己是一个构造函数 实例化出一个对象

1.最简Promise

 //最简Promise  
    //resolve 成功时的回调函数
    //reject 失败时的回调函数  
    new Promise((resolve,reject)=>{
        let index = true

        if(index === true){
            resolve(100);  //成功触发
        }
        if(index === false){
            reject('出错啦');  //失败触发
        }
    })
    //then 接收成功函数的回调
    .then(function(res=1){  //成功的回调
        console.log(res);
    })
    //catch 接收失败函数的回调
    .catch(function(err =0){ //失败的回调
        console.log(err);
    })

2.体会带有异步的Promise

    //最简Promise  
    //resolve 成功时的回调函数  
    new Promise((resolve,reject)=>{
        //异步触发Promise 成功回调
        //3秒后触发成功
        setTimeout(()=>{
            resolve(2000)
        },3000)
    })
    .then(function(res=1){  //成功的回调
        console.log(res);
    })
    .catch(function(err =0){ //失败的回调
        console.log(err);
    })

3.体验带有异步请求的Promise

  new Promise((resolve,reject)=>{
        //发送请求
        $http.get('data.json',res=>{
                //请求成功
                if(res.id == 42){
                    resolve(res)
                }else{
                    reject('请求失败')
                }

         })
    })
    .then((res)=>{
        console.log(res)
        console.log('请求成功');
    })
    .catch((err)=>{
        console.log('请求失败');
    })

4.利用Promise 重写 多层ajax 回调

   new Promise((resolve,reject)=>{
        //发送请求
        $http.get('data.json',res=>{
                //请求成功
                if(res.id == 42){
                    resolve(res)
                }
         })
    })
    .then((res)=>{
        console.log('第一层请求成功');
        console.log(res);

        //第二层请求开始 
        return new Promise((resolve,reject)=>{
            $http.get('data1.json?id='+res.id,res1=>{
                if(res1.code ==0){
                    resolve(res1);
                }    
            })
        })

    })
    .then((res1)=>{
        console.log('第二层请求成功');
        console.log(res1);

        //第三层请求
        return new Promise((resolve,reject)=>{
            $http.get('data2.json?id=3',res2=>{
                if(res2.orderId){
                    resolve(res2)
                }
            })
        })
    })
    .then(res2=>{
        console.log('第三层请求成功');
        console.log(res2);
    })

5.优化Promise ajax请求

//第一步 提取公共的js代码进行封装
  //获取参数
    //封装Promise 与ajax
    function getData(url,data){
        //如果有参数就拼接
        if(data){
            url +='?'+data;
        }
       return new Promise((resolve,reject)=>{
            //发送请求
            $http.get(url,res=>{
                    //请求成功
                    if(res.status ===0){
                        resolve(res)
                    }
            })
        })
    }

    getData('data.json').then((res)=>{
        console.log(res);
       return getData('data1.json','id='+res.id)
    })
    .then((res1)=>{
        console.log(res1);
      return  getData('data2.json','id=3')
    })
    .then(res2=>{
        console.log(res2);
    })
// 第二步 es6语法极致简化
   //获取参数
    //封装Promise 与ajax
    function getData(url,data){
        //如果有参数就拼接
        if(data){
            url +='?'+data;
        }
       return new Promise((resolve,reject)=>{
            //发送请求
            $http.get(url,res=>{
                    //请求成功
                    if(res.status ===0){
                        resolve(res)
                    }
            })
        })
    }
    getData('data.json')
    .then(res=>getData('data1.json','id='+res.id))
    .then(res1=>getData('data2.json','id=3'))
    .then(res2=>{
        console.log(res2);
    })

axios 插件

作用:ajax封装的插件,三方包

//实现上面的请求

axios('data.json')
    .then(res=>axios('data1.json',{params:{id:res.id}}))
    .then(res1=>axios('data2.json',{params:{id:3}}))
    .then(res2=>{
        console.log(res2.data);
    })

async await

异步问题:异步中某个变量的值重新改变,后面的代码拿不到最新的值
let a = 1;
//先同步后异步
setTimeout(()=>{
    a=2;
},0)

console.log(a);  //1

async await作用:将异步操作变为同步操作

声明异步函数

    //async await 语法
    //async 声明该函数有异步操作 一般写在函数 function 的前面
    //await 等待异步执行完毕,和async连用

    //声明异步函数
    async function getData(){

    }
    //表达式声明异步函数
    const getData1 = async function(){

    }

    //Es6 写法 箭头函数
    const getData2 = async ()=>{

    }

实现:将异步定时器改为同步

    console.log(1);
        const timer = ()=>{
            return new Promise((resolve,reject)=>{
                setTimeout(() => {
                    console.log(2);
                    resolve('成功了')
                }, 0)
            })
        }

    const num = async () => {
        console.log(1.5);
        await timer();
        console.log(3);
        console.log(4);
    }
    num()

完美实现:将异步ajax改为同步

 // 1.先把异步代码放到 声明的异步函数中
    const getData = async ()=>{
        //2.在异步操作的的前面加上await 实现同步化
        const res = await axios('data.json');
        const res1 = await axios('data1.json',{params:{id:res.id}});
        const res2 = await axios('data2.json',{params:{id:3}});
        console.log(res2.data);
    }
    getData();
喜欢 (0)
cat
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址