美文网首页
promise几种用法

promise几种用法

作者: 超人鸭 | 来源:发表于2020-05-12 18:02 被阅读0次

    .then的链式调用

    1. promise.then()可以接受两个参数,都是函数,第一个参数为promise状态成功时执行,第二个参数为promise状态失败时执行,在.then的时候就会立即执行
    2. promise.then()也会返回一个promise,并把参数函数的返回值传给返回的promise,如果是执行第一个参数函数也就是resolve,那返回的promise也是成功状态的
    3. 如果是执行第二个参数也就是reject,那返回的promise就是失败状态的
    4. 如果是执行第一个函数也就是resolve,那这个函数返回的值就是返回的promise resolve的值,就是.then的参数
    5. Promise.resolve也会返回一个promise实例,并且状态为resolved的,当这个返回的promise执行.then方法的时候,会立即执行第一个参数函数,Promise.resolve的参数就会是返回promise.then方法第一个参数函数的参数、

    实例:

    let a = {
      foo: 'bar'
    }
    
    let promise = Promise.resolve(a) // 声明一个成功状态的promise,并把a对象当成resolved的值
    
    // 对promise重新赋值四次,会立即执行testRes方法
    promise = promise.then(testRes)
    promise = promise.then(testRes)
    promise = promise.then(testRes)
    promise = promise.then(testRes)
    
    // 对a对象进行处理,为随机赋值一对key-value,再将返回出去
    let testRes = function (a) {
      a[`test${parseInt(Math.random() * 100)}`] = parseInt(Math.random() * 10)
      return a
    }
    

    当执行第一个promise = promise.then(testRes)时,会立即执行testRes方法,而参数就是初始化的a,因为在上面,promise的初始值就是一个成功状态的promise,并且resolve的值是a,赋值后的promise也是一个promise对象,并且resolve的值就是处理一次的a对象,最后打印:

    promise.then((res) => {
      console.log(res)
      //{foo: "bar", test90: 5, test35: 9, test23: 8, test44: 9}
    })
    

    这个用法是axios库的拦截器中使用到,使用过的朋友应该知道,axios的拦截器就是将config或者response进行一层一层的传递,处理。

    与await结合

    直接看例子:

    async function test() {
      // 原始写法
      const promise = new Promise((resolve, reject) => {
        let num = parseInt(Math.random() * 10)
        if (num >= 5) {
          setTimeout(() => {
            resolve(`${num}成功`)
          }, 1000)
        } else {
          setTimeout(() => {
            reject(`${num}失败`)
          }, 1000)
        }
      })
      promise.then((res) => {
        // console.log(res) // 成功
      }).catch((err) => {
        // console.log(err) // 捕获错误,不会报错
      })
    
     /*
       * await无返回值情况
       * const result = await promise这种写法,如果promise成功的情况,那result会拿到.then成功函数的参数也就是上面的res
       * 如果promise失败的情况,那会报错,不会再往下执行
      */
      const result = await promise
      console.log(result)
    
    /*
      * await有返回值情况
      *这种通过promise返回的情况,result拿到就是具体返回的内容,能捕获错误不会报错,推荐这种写法
      */
      const result = await promise.then((res) => {
        return res
      }).catch((err) => {
        return err
      })
      console.log(result)
    }
    test()
    

    推荐最后一种写法

    异步分离

    指的是定义一个pending状态,然后先定好promise成功情况后操作,然后由外部控制这个promise什么时候变成resolved状态,去执行.then操作,先看一个最简单的例子:

    // 定义一个变量来控制promise的状态:
    let timingFn
    
    let promise = new Promise((resolve, reject) => {
      timingFn = resolve // 将resolve函数赋值给外部的变量
    })
    
    promise.then((res) => {
      console.log(res) // 两秒后打印11
    })
    
    // 外部决定什么时候resolve
    setTimeout(() => {
      timingFn('11')
    }, 2000)
    

    再看一个较为复杂的例子,由内部控制promise resolve执行的逻辑,外部只是控制promise的状态,主要运用到函数的参数知识:

    let timingFn // 外部控制状态的变量
    
    class TestWrapperFn {
      promise
      constructor(wrapperFn) {
        let resolveFn
        this.promise = new Promise((resolve, reject) => {
          resolveFn = resolve
        })
        /**
        * wrapperFn 由外部传入,会有一个参数, 这个参数外部无法写逻辑, 由内部定义的
        * 这个参数也是一个函数,这里内部给定义成promise的resolve函数,这个函数在内部只是定义,不会执行,由外部执行
        * 当这个函数在外部执行了,promise的状态就变成resolved,会执行then方法
        */
        wrapperFn(() => { // 这里的参数函数只是定义,不会执行
          resolveFn('test')
        })
      }
    }
    
    // 这里的Fn2就是上面类中定义的wrapperFn的参数函数
    const testWrapperFn = new TestWrapperFn(function wrapperFn(fn2) {
      timingFn = fn2
    })
    
    setTimeout(() => {
      timingFn()
    }, 2000)
    
    testWrapperFn.promise.then((res) => {
      console.log(res) // 两秒后打印test
    })
    

    这就是超人鸭这次分享的几个promise用法,主要是在学习axios库时总结的dome,感觉自己对promise的理解也是非常浅,如果你对promise有更好的理解,欢迎指教。

    作者微信:Promise_fulfilled

    相关文章

      网友评论

          本文标题:promise几种用法

          本文链接:https://www.haomeiwen.com/subject/zrxinhtx.html