• Promise代码详解(show you the code)


    认识异步函数

    1.  同步函数:
       const sum1 =(a,b)=>{
         return a+b
       }
       console.log('AAA');
       console.log(sum(5,6));
       conosle.log('BBB')
      
       异步函数:封装一个函数,这个函数2秒后返回a+b的和
       const sum2 =(a,b,callback)=>{
         setTimeout(()=>{
            callback(a+b)
         },2000)
       }
      
       console.log('AAA')
       sum2(2,3,(result)=>{
          console.log(result)
       })
       console.log('BBB')
      
       错误事例:
       const sumAfter2s = (a, b) => {
         setTimeout(() => {
           return a + b;
         }, 2000);
       }
       这里面的return是定时器的这个函数的返回值,外部函数没有返回值
      
    2. 异步(Asynchronouse):不阻塞CPU,CPU先执行别的程序,这段程序被挂起,等它执行完,执行他的回调函数
    3. 目前的结论:同步函数,自己有返回值,而异步函数没有返回值(个人理解:为什么没有返回值,要拿到他的返回值肯定是有其作用,作用就是有用处,而异步函数会等其他的程序执行完在执行,所以在返回值也没有其作用了)

    认识回调黑洞

    • 也叫做回调地狱,callback hell
    • 回调套回调,层次很多,这样会产生回调黑洞
    •   比如利用刚才的sum2这个函数,计算3,4的和,在把这个值与5相加,这些和在与6相加 
        三次计算两个数之和
        sum2(3,4,(r1)=>{
          console.log(r1)
          sum2(r1,5,(r2)=>{
            console.log(r2)
              sum2(r2,6,(r3)=>{
                console.log(r3)
              })
          })
        })
      
        这样的代码难以阅读,和维护,叫做回调黑洞
      
    • 下面引入Promise,来解决回调地狱

    Promise -写同步的方法,写异步

    • 认识到生活中的电器缺少锲约
      • 生活中的电器都是异步工作的,他们工作的时候人不会被阻塞,人可以干别的
      • 这些电器在结束工作之后,干的事儿不同,通知形式也不同
      • 洗衣机在结束工作后,播放春天在哪里,微波炉工作结束后滴的一声
      • 通知形式不同的哲学就是:缺少契约
      • Promise就是为了统一这种契约来的:Promise生而为契约

    Promise的基本使用

    1.  原始:
       const sum2 =(a,b,callback)=>{
         setTimeout(()=>{
            callback(a+b)
         },2000)
       }
       使用Promise:
       const sum2=(a,b)=>{
         return new Promise((callback)=>{
           setTimeout(()=>{
             callback(a+b)
           },2000)
         })
       }
       这里重写了num2方法,不同的是,
       这个函数返回Promise类的实例,在new Promise()的时候,要求传入真正的回调函数。
       new Promise(()=>{})里面做异步语句,异步结束后,调用callback()函数,将a+b传回来
       也就是说定义确实变的麻烦了,但是,调用它的时候,也换来了快感,此时的异步函数是有返回值的
      
       async function main(){
         console.log('AAAA');
         const r1 = await sum2(3, 4);
         const r2 = await sum2(r1, 5);
         const r3 = await sum2(r2, 6);
         console.log(r1);
         console.log(r2);
         console.log(r3);
         console.log('BBBB');
       }
       main();
      
       es6规定,async是标记异步函数的,await后面可以等一个Promise的实例
       有await语句的函数前面必须加async标记,并且箭头函数不行
      
       Promise实例天生就有三种状态:pending(进行中),fulfilled(结束),rejected(失败).
       一上来就处于pending状态,Promise只有它自己内部的语句,能够把它切换成filfilled的状态。
      
       -什么时候切换呢?
       就是new Promise()的时候传入的那个函数的形参被调用的时候,Promise状态会变为fulfilled。
       同时resolve()函数中的参数,将成为这个函数的返回值
      

    Promise实际运用

    1.  顺序读取文件的例子
       原始:
       const fs = require('fs')
      
       fs.readFile('./a.txt',(err,nr1)=>{
         console.log(nr1.toString());
         fs.readFile('./b.txt',(err,nr1)=>{
           console.log(nr2.toString());
           fs.readFile('./c.txt',(err,nr1)=>{
             console.log(nr3.toString());
           })
         })
       })
      
       使用Promise干掉回调地狱,但是使用的时候都要封装
       const doFile=(filename)=>{
         return new Promise((resolve)=>{
           fs.readFile(filename,(err,nr)=>{
             resolve(nr.toString())
           })
         })
       }
       调用:
       async function main(){
         const nr1 = await doFile('./a.txt')
         console.log(nr1);
         const nr2 = await doFile('./b.txt')
         console.log(nr2);
         const nr3 = await doFile('./c.txt')
         console.log(nr3)
       }
       main();
      
    2.  Ajax顺序读取接口1,2,3
       原始地狱写法:
       $.get('jiekou1.java',(data1)=>{
         alert(data1);
         $.get('jiekou2.java',(data2)=>{
           alert(data2);
           $.get('jiekou3.java',(data3)=>{
             alert(data3);
           })
         })
       })
      
       使用Promise解决,先封装一下
       const qingqiu = (url)=>{
         return new Promise((resolve)=>{
           $.get(url,data=>{
             resolve(data);
           })
         })
       }
       封装挺恶心的,但是换回的是调用的快感
       async function main(){
         const nr1 = await qingqiu('jiekou1.java')
         alert(nr1);
         const nr2 = await qingqiu('jiekou2.java')
         alert(nr2);
         const nr3 = await qingqiu('jiekou3.java')
         alert(nr3) 
       }
       
       用Axios解决封装的麻烦,Axios这个包封装了Promise版的Ajax,把Aajx封装到了Promise里面了
       <script>引入Axios包</script>
       async function main(){
       		const nr1 = await axios.get('jiekou1.php').then(data => data.data);
       		const nr2 = await axios.get('jiekou1.php').then(data => data.data);
       		const nr3 = await axios.get('jiekou1.php').then(data => data.data);
      
       		alert(nr1);
       	}
      
       	main();
      
    3.  再vue中axios
       {
         data(){
           return {
             
           }
         },
         methods:{
           async loadData(){
             const jg = await axios.get('').then(data=>data.data);
             this.jg = jg
           async changePage(){
             const jg =await axios.get('').then(data=>data.data);
           }
           async changePageSize(){
             const jg =await axios.get('').then(data=>data.data);
           }
           }
         }
       }
      

    理解Promise契约

    1.  将大家都统一了起来
       const xiyifu = (脏衣服,洗衣粉) => {
         return new Promise((resolve) => {
           进水、
           进洗衣粉、
           洗20分钟、
           排水、
           再进水、
           漂水、
           放水、
           resolve(干净衣服);
         });
       }
       const menfan = (冷饭) => {
         return new Promise((resolve) => {
           加蒸汽、
           再加蒸汽、
           再加蒸汽、
           resolve(热饭);
         });
       }
       
       async function main(){
         const a = await xiyifu('内裤');
         const a = await menfan('米粒');
       }
      

    Promise方便调错

    1.  try...catch...捕获的“可能发生”的错误,不会影响程序正常执行
       console.log(1);
       console.log(2);
       console.log(3);
       try{
         console.log('★');
         asdfasdflkajsdlfjk
       }catch(e){
      
       }
       console.log(4);
       console.log(5);
       // 打印  1 2 3 ★ 4 5
      
       异步函数不能被try...catch...
      
       const sumAfter2s = (a, b) => {
         return new Promise((resolve, reject) =>{
           setTimeout(() => {
             if(a + b > 10){
               resolve(a + b);
             }else {
               reject('两个数字太小')
             }
           }, 2000);
         });
       };
      
       sumAfter2s(3, 4).then(data => {
         console.log(data);
       }).catch(e => {
         console.log(e);
       })
      

    面试题参考

    1.  只写一行语句,实现效果:
       async function foo(){
       // 等到2秒
       await _________________________________________________
       alert('你好');
       }
       foo();
      
       答案:
       <script type="text/javascript">
       	async function foo(){
       		// 等到2秒
       		const a = await new Promise((resolve) => {
       			setTimeout(() => {
       				resolve(34)
       			}, 2000)
       		});
       		alert(a);
       	}
      
       	foo();
       </script>
      
  • 相关阅读:
    使用牛顿迭代法和二分法求解一个数的平方根(python语言实现)
    厄拉多塞筛法和普通方法求素数表(python实现)
    使用辗转相除法求两个数的最大公因数(python实现)
    我在博客园第一篇博文
    Linux安装maven
    MyBatis基础入门
    Maven的使用入门
    nginx的简单使用和使用nginx在windows上搭建tomcat集群
    后端程序员如何玩转AJAX
    Servlet3.0文件上传
  • 原文地址:https://www.cnblogs.com/JCDXH/p/11767862.html
Copyright © 2020-2023  润新知