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的基本使用

 //原始:
 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契约

 //将大家都统一了起来
 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方便调错

 //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);
 })

八、面试题参考

 只写一行语句,实现效果:
 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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值