最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 拼拼凑凑的Promise

    正文概述 掘金(baby00700)   2020-12-31   445

    一、 为什么是 Promise?

    1 所有的 js 代码都是单线程执行的。

    所有的事件,渲染,一切都是单线程的,我们并不希望个耗时操作阻塞用户进程,于是就有了异步的概念。

    1.1 异步的基本原理

    JavaScript 引擎负责解析,执行 JavaScript 代码,但它并不能单独运行,通常都得有一个宿主环境,一般如浏览器或 Node 服务器,前文说到的单线程是指在这些宿主环境创建单一线程,提供一种机制,调用 JavaScript 引擎完成多个 JavaScript 代码块的调度,这种机制就称为事件循环( Event Loop )。
    

    1.2 异步的常见实现方法

    • 回调函数
    • Promise对象
    • Generator

    1.3 为什么选择 Promise

    1.3.1 回调函数

    回调函数在处理越多的异步逻辑时,就需要越深的回调嵌套(回调地狱):

    1.代码逻辑书写顺序与执行顺序不一致,不利于阅读与维护。
    
    2.异步操作的顺序变更时,需要大规模的代码重构。
    
    3.回调函数基本都是匿名函数,bug 追踪困难。
    
    1.3.2 Generator

    Generator 虽然也可以实现异步,但他仍是一个新的标准。 推荐大家去尝试一下这种新的写法。 不仅仅是在 dva 中使用。

    Promise 可以更直观,更易用的方式 来解决 "回调地狱"

    二、什么是 Promise?

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
    

    有个标准叫做: Promises / A +

    ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

    Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject

    Promise 新建后就会立即执行。

    new Promise((resolve, reject) => {
      resolve(1)
    })
    new Promise((resolve, reject) => {
      reject(1)
    })
    

    1 术语

     "promise"是具有then方法的对象或函数,其行为符合此规范。
    
     "thenable"是定义then方法的对象或函数。 thenable对象指的是具有then方法的对象。
    
     "value"是任意合法的Javascript值,(包括undefined,thenable, promise)
    
     "exception"是使用throw语句抛出的值
    
     "reason"是表示promise为什么被rejected的值
    
    

    2 Promise 相当于一个状态机

    一个 promise 必须处于三种状态之一: 请求态(pending), 完成态(fulfilled),拒绝态(rejected)

    • 当promise处于请求状态(pending)时,promise可以转为fulfilled或rejected状态
    • 当promise处于完成状态(fulfilled)时
      • promise不能转为任何其他状态
      • 必须有一个值,且此值不能改变
    • 当promise处于请求状态(pending)时
      • promise不能转为任何其他状态
      • 必须有一个原因(reason),且此原因不能改变
    #### 3 Promise 的方法(常用)
    3.1 then()

    Promise.prototype.then()

    then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

    // 基本使用
    new Promise((resolve, reject) => {
      resolve(1)
    })
    .then(value => {
      console.log(value) // 1
    })
    
    

    一般来说,不要在then()方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

    // then 捕获错误(不建议)
    
    // bad
    new Promise((resolve, reject) => {
      resolve(1)
    })
    .then(success => {
      console.log(success) // 1
    }, error => {
      console.log(error)
    })
    
    // bad
    new Promise((resolve, reject) => {
      reject(1)
    })
    .then(success => {
      console.log(success)
    }, error => {
      console.log('then 捕获错误', error) // then 捕获错误 1
    })
    .catch(error => {
      console.log('catch 捕获错误', error) // 思考:这行会被执行吗??
    })
    
    3.2 catch()
    // 基本使用
    new Promise((resolve, reject) => {
      reject(1)
    })
    .catch(e => {
      console.log('e',e) // e 1
    })
    

    关于错误捕获:

    // try...catch() ?
    try{
      y + 1
    }catch(e){
     console.log('try...catch捕获的错误=>',e) // try...catch捕获的错误=> ReferenceError: "y is not defined"
    }
    
    // try ...promise... catch() ?
    
    // 1.
    try{
      new Promise((resolve, reject) => {
      	reject(1)
        c + 1
      })
    }catch(e){
     console.log('try ...promise... catch捕获的错误=>',e) // 思考:c+1 能否被捕获??
    }
    
    // 2.
    try{
      new Promise((resolve, reject) => {
      	reject(1)
        c + 1
    	})
      .catch(e => {
        console.log('promise catch捕获的错误',e)  // 思考:c+1 能否被捕获??
        cc + 1
      })
    }catch(e){
     console.log('try ...promise... catch捕获的错误=>',e) // cc+1 思考:能否被捕获??
    }
    
    // 3.
    try{
      new Promise((resolve, reject) => {
      	reject(1)
        c + 1
    	})
      .catch(e => {
        console.log('promise catch捕获的错误',e) // 思考:c+1 能否被捕获??
        cc + 1
      })
      .catch(e => {
         console.log('promise catch捕获的错误2',e) // cc+1 思考:能否被捕获??
      })
    }catch(e){
     console.log('try ...promise... catch捕获的错误=>',e) // cc+1 思考:能否被捕获??
    }
    
    3.3 all()

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    只有当所有的promise执行完毕并得到结果后才会更改外部promise的状态,并且返回全部的promise的结果。

    const promiseList = [0,1,2,3,4,5].map(t => {
      return new Promise((resolve,reject) => {
        resolve(t+1)
      })
    })
    
    Promise.all(promiseList).then(res => {
      console.log(res) // [1,2,3,4,5,6]
    })
    
    3.4 race()

    Promise.race()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    只有最早执行完毕的promise会更改外部包装promise的状态,并且只返回最早的promise结果。

    
    // race()
    const promise1 = new Promise((resolve,reject) => {
      setTimeout(()=>{
        resolve('1000')
      },1000)
    })
    
    const promise2 = new Promise((resolve,reject) => {
      setTimeout(()=>{
        resolve('500')
      },500)
    })
    
    Promise.race([promise1,promise2]).then(res => {
      console.log(res)  // '500'
    })
    
    3.5 finally()

    三、一些思考

    1 then()中有then() ?

    2 catch() + then() ?

    3 如何使用Promise ?

    4 all() 的catch() ?


    起源地下载网 » 拼拼凑凑的Promise

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元