promise入门

前言

老生常谈promise
对于promise大部分人应该不陌生了,他是ES6的新特性之一,如果你是一个追求潮流的coder那么你应该用过axios请求方式,这个向后台发送请求的方式就用到了promise
我接触promise是一年前,部门的程序员会轮流培训,刚好当时我在看一些关于axios的东西,就准备培训一些关于promise的知识,所以我就找了很多关于promise的博客,看的也是云里雾里,可想而知培训的效果也不是很好

promise再探

promise很火,可以说是程序员居家旅行必备的技能之一了,所以说对于这样的东西,我们最好还是吃透它,这样才不会在代码当中迷失。

promise的作用

大多数人开发的过程中应该都会遇到一些异步的问题,比如我们必须等请求接口返回数据后才去做另外一些事情,我们都是通过回调函数来做
大部分好的情况是只需要等待一个异步的结果就可以去做一些事情,那么极端的情况是不同的异步嵌套,让我们的代码看上去就像一个金字塔,一层层的异步嵌套让我们头皮发麻,这种情况被我们称为回调地狱

fs.readFile('./sample.txt', 'utf-8', (err, content) => {
    let keyword = content.substring(0, 5);
    db.find(`select * from sample where kw = ${keyword}`, (err, res) => {
        get(`/sampleget?count=${res.length}`, data => {
           console.log(data);
        });
    });
});
回调的缺点
  • 嵌套太深,难以维护
  • 无法正常使用return和throw
  • 无法正常检索出堆栈信息

promise就可以解决这些问题,可以让我们的代码跟优雅更具有可读性,给promise下个定义

promise是异步编程的一种解决方案,比回调函数更何理更强大
promise是一个代理对象,它和原先的操作并未关系,我们只需要把原先的操作放入执行器里
它通过一个回调函数,然后把其它的回调全部基于此回调函数

我们从使用层面上再来定义以下promise

  • 主要用于异步计算
  • 可以将异步操作队列化,让程序按照期望的顺序来执行,返回符合预期的结果
  • 可以在对象之间传递和操作promise,帮助我们处理队列
同步和异步

大家都知道同步和异步,但是让你给他下个定义你知道吗?

一般而言,操作分为两种发出调用和得到结果,发出调用立即得到结果为同步,发出调用,无法立即得到结果,需要一些额外的操作才能得到预期的结果为异步。同步是在发出调用后一直等待程序是阻塞状态,异步发出调用后程序可以继续执行

异步操作的常见用法
  • 事件侦听与响应
dom.addEventListener(type,callback)
$(dom).on(type,callback)
  • 在浏览器中异步操作以事件为主

promise的三种状态

  • pendding 实例化时候的状态
  • fullfilled 操作成功后
  • rejected 被否决操作失败

promise实例的后两种状态一经改变后不会再次改变,比如状态改成fullfilled不会在改成rejected

promise的结构

 new Promise((resolve,reject)=>{
      //此处执行一段异步代码 (这个部分被称为执行器)
      //异步处理有结果之后执行对应的
      resolve() //操作成功调用此回调,把promise实例的状态改成fullfilled
      reject()   //操作失败调用此回调,把promise实例的状态改成rejected
  }).then((res,rej) => {

})

在then函数里返回一个新的promise,then支持两个参数(这个地方有一个坑 因为需要手动return),分别对应上一个promise实例的两个回调
then可以链式的调用,当前面一个promise的状态改变时,后面的then会根据前面一个promise的状态执行对应状态的回调

image.png

借用慕课网老师的一张图,看一下整个流程

  • 实例化promise
  • 执行器执行一段异步代码
  • 判断异步代码执行成功或者失败分别调用resolve()或者rejected()
  • resolve()或者rejected()改变promise实例的状态fullfilled或者rejected
  • 执行then里面的对应promise状态的回调,fullfilled执行res(),rejected执行rej()
  • then返回新的promise(需要使用return关键字)
  • 下一个then会根据新返回来的promise的实例执行对应状态的res()或者rej()
  new Promise((resolve,reject)=>{
      setTimeout(()=>{
          resolve('hello')
      },3000)
  }).then(
      res =>{
          return  res+ ' world'
      }
  ).then(
      res =>{
          console.log(res) // hello world
      }
  ).catch(
   err=>{
      console.log(err)
   }
      
  )

就先简单介绍到这里吧
下周我会写一些用法,以及使用过程中常用的错误

推荐阅读更多精彩内容