Promise总结(一)

/ 0评 / 0

由于最近在筹备小程序大赛,需要与后端进行配合开发。借此机会,来认真总结并顺便温习一下Promise,此篇亦可以作为面试前的Promise知识复习。当然,这其中并不包含手写系列(会在后面的文章总结一个手写系列)。

好久没写技术博客了,认真想了一下,这有悖于当初创建博客的初心。因此,后续大概会一个星期出一篇技术博客,来总结未来面试中可能遇到的知识点,也将自己对知识的理解和记忆更牢固一点。


什么是Promise?

Promise是ES6中新规定的一门技术,是JavaScript中进行异步编程的新解决方案,当然,之前的旧方案是指:单纯使用回调函数。因此,Promise的出现很好地解决了"回调地狱"的情况。这么说,可能有点抽象。具体是指:1.从语法上来讲:Promise是一个构造函数 2.从功能上来讲:Promise对象用来封装一个异步操作并可以获取其成功或失败的结果

常见的异步操作有:使用Node.js中的fs模块进行文件操作、数据库(MySQL/mongoDB)操作、Ajax进行网络请求、定时器等。

fs文件操作:
  require('fs').readFile('./index.html', (err, data) => { ... })
Ajax网络请求:
  $.get('/server', data => { ... })
定时器:
  setTimeout(() => { ... }, 1000)

为什么上面用的是回调函数,而不是Promise呢?

Promise相对于之前的回调函数有什么优势吗?(面试知识点)

1.Promise支持链式调用可以解决回调地狱问题

什么是回调地狱?

回调地狱即是回调函数嵌套使用外部回调函数异步执行的结果嵌套的回调函数执行的条件

asyncFunc1(opt, (...arg1) => {
   asyncFunc2(opt, (...arg2) => {
      asyncFunc3(opt, (...arg3) => {
         asyncFunc4(opt, (...arg4) => {
          ......
      })
    })
  })
})

回调地狱的缺点?

不便于阅读、不便于异常处理

2.指定回调函数的方式更加灵活

使用旧方式时,必须在启动异步任务前指定;而Promise,不需要,其启动过程:启动异步任务 => 返回Promise对象 => 给Promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)

这里举个例子:使用Promise模拟抽奖

<div>
   <button id="btn">点击抽奖</button>
</div>
<script>
   /**
    *  模拟需求:点击按钮,1s后显示是否中奖(30%中奖率),若中奖则弹出"恭喜中奖";反正,则弹出"再接再厉"
    */

    // 生成随机数
    function rand(m, n) {
       return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
    }

    1.传统方法
    const btn = document.querySelector('#btn');
    btn.addEventListener('click', function() {
       setTimeout(() => {
         let n = rand(1, 100);
         if(n <= 30) {
            alert('恭喜中奖');
         } else {
            alert('再接再厉');
        }
      }, 1000)
    })

    2.Promise
      // 实例化Promise时,需要传入一个回调函数,并且函数的形参也是函数;即resolve, reject是函数类型的数据
    btn.addEventListener('click', function() {
       const p = new Promise((resolve, reject)=>{
            // 处理异步操作
            setTimeout(() => {
              let n = rand(1, 100);
              if(n <= 30) {
                 resolve(n); -> 执行resolve函数,将Promise对象设置为fulfilled(resolved)状态(已成功),可以进行传参
              } else {
                 reject(n); -> 执行reject函数,将Promise对象设置为rejected状态(已失败),可以进行传参
              }
           }, 1000)
       });
       // 执行了相应的函数并不代表能给出对应的内容,只能代表当前Promise对象处于哪种状态
       // 想要得到结果,必须调用Promise对象的then方法。同样,then方法的参数也是两个函数类型数据,分别对应Promise对象处于resolved状态和rejected状态
       p.then((value) => {
          alert('恭喜中奖,中奖号码是' + value);
       }, (reason) => {
          alert('再接再厉,号码是' + reason);
       })
    });
</script>

发表评论

渝公网安备 50010102001052号

/

渝ICP备2021009595号