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

    正文概述 掘金(蓝_风)   2020-12-03   424

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

    场景说明

    图片依次的加载

    function(){
        var img1 = document.createElement('img')
    	img1.onload = function () {
    	    var img2 = document.createElement('img')
    	    img2.onload = function(){
    	        var img3 = document.createElement('img')
    	        img3.onload = function(){
    	            // ....
    	        }
    	    }
        }
    }
    

    这就是所谓的回调地狱,很显然,逻辑稍微复杂一些项目就很难维护了

    Promise 的三种状态

    • pending-进行中,不会触发then 和 catch
    • resolved-已完成,会触发后续的 then 回调函数
    • rejected-已失败,会触发后续的 catch 回调函数
    状态变化是不可逆的 (fulfilled不可能变为pending, rejected不可能变为pending状态)
    

    then和catch改变状态

    • then 正常返回resolved,里面有报错则会返回rejected
    const p1 = Promise.resolve().then(() => {
      return 100
    })
    console.log('p1', p1)
    // resolve 触发后续的 then 回调
    p1.then(() => {
      console.log(123)
    })
    const p2 = Promise.resolve().then(() => {
      throw new Error('then error')
    })
    // rejected 触发后续 catch 回调
    console.log('p2', p2)
    p1.then(() => {
      console.log('456')
    }).catch(err => {
      console.error('error100', err)
    })
    
    • catch 正常返回resolved,里面有报错则会返回rejected
    const p3 = Promise.reject('my error').catch(err => {
      console.log(err)
    })
    console.log('p3', p3) // reject 里没有报错,状态为resolved 触发后续 then
    p3.then(() => {
      console.log(100)
    })
    const p4 = Promise.reject('my error').catch(err => {
      throw new Error('catch error')
    })
    console.log('p3', p4) // 状态为rejected 触发后续 catch
    
    p4.then(() => {
      console.log(200)
    }).catch(() => {
      console.log('somef error')
    })
    

    Promise的基本用法

    loadImg(src) => {
      // new Promise实例,接受两个参数(resolve,reject)
      const promise = new Promise((resolve, reject) => {
        var img = document.createElement('img')
        img.onload = () => {
    	  resolve(img)
    	}
    	img.onerror = () => {
    	  reject('图片加载失败')
    	}
        img.src = src
      })
      return promise
    }
    var src = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
    var result = loadImg(src)
    result.then((img) => {
      console.log('图片的宽度' + img.width)
    }, () => {
      console.log('failed')
    })
    // 运行结果图片的宽度117
    

    Promise多个串联

    loadImg(src) => {
      // new Promise实例,接受两个参数(resolve,reject)
      const promise = new Promise((resolve, reject) => {
        var img = document.createElement('img')
        img.onload = () => {
    	  resolve(img)
    	}
    	img.onerror = () => {
    	  reject('图片加载失败')
    	}
        img.src = src
      })
      return promise
    }
    // 多个串联
    const src1 = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
    const result1 = loadImg(src1)
    const src2 = 'https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=559043697,829837996&fm=85&s=816240A611420EFE36F52D900300E082'
    const result2 = loadImg(src2)
    result1.then((img1) => {
      console.log('第一张图片')
      return result2 
    }).then((img2) => {
      console.log('第二张图片')
    }).catch((ex) => {
      // 统一处理异常
      console.log(ex)
    })
    

    Promise.all() && Promise.race()

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

    loadImg(src) => {
      // new Promise实例,接受两个参数(resolve,reject)
      const promise = new Promise((resolve, reject) => {
        var img = document.createElement('img')
        img.onload = () => {
    	  resolve(img)
    	}
    	img.onerror = () => {
    	  reject('图片加载失败')
    	}
        img.src = src
      })
      return promise
    }
    const src1 = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
    const result1 = loadImg(src1)
    const src2 = 'https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=559043697,829837996&fm=85&s=816240A611420EFE36F52D900300E082'
    const result2 = loadImg(src2)
    // Promise.all 接收一个 promise 对象的数组
    // 待全部完成之后,统一执行success
    Promise.all([result1, result2]).then((datas) => {
      // 接收到的datas 是一个数组,依次包含了多个promise返回的内容
      console.log('all', datas[0])
      console.log('all', datas[1])
    })
    // Promise.race 接受一个包含多个 promise对象的数组
    // 只要有一个完成,就执行 success
    Promise.race([result1, result2]).then((data) => {
      // 接收到的datas 是一个数组,依次包含了多个promise返回的内容
      console.log('race', data)
    })
    

    Promise.all方法接受一个数组作为参数,p1、p2、p3都是Promise对象的实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。

    Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,


    起源地下载网 » 简谈Promise

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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