promise几种用法

2020-05-12  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读