Promise的学习

63 阅读4分钟

Promise的学习

Promise的使用

function foo() {
  // 传入的回调函数,称之为: executor(执行者)
  return new Promise((resolve, reject) => {
    // resolve('success')
    reject('err')
  })
}

// 1.then()里面可以传二个回调函数进行成功和失败处理
const promise2 = foo()
promise2.then(res => {
  console.log(res);
},err => {
  console.log(err);
})

// 2.在then里处理成功,在catch里处理失败.
const promise1 = foo()
promise1.then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})


// 3.钩子函数: hook , 相当于 回调函数
function bar(fn) {
  fn()
}

bar(() => {

})

Promise的三种状态

/**
 * 注意: Promise的状态一旦确定下来, 那么就是不能更改的 (锁定)
 */
new Promise((resolve, reject) => {
  // 状态一: pending(待定)
  console.log('立即执行');
  // 开始锁定状态(resolve/reject)
  resolve('success') // 状态二: fulfilled(已兑现)
  reject('err') // 状态三: rejected(已拒绝)
  console.log('还是会执行');
}).then(res => {
  console.log(res);
}, err => {
  console.log(err);
})

Promise的resolve参数

/**
 * resolve(参数)
 * 1> 传入普通值或者对象.
 * 2> 传入一个Promise, 当前的Promise状态由传入的Promise决定.
 *    相当于状态进行了移交.
 * 3> 传入一个对象, 并且这个对象有实现then方法.
 *    那么会执行该then方法,由then方法决定状态.
 */
// new Promise((resolve, reject) => {
//   resolve(new Promise((resolve, reject) => {
//     resolve('aaaa')
//   }))
// }).then(res => {
//   console.log(res);
// }, err => {
//   console.log(err);
// })


// 传入对象,实现then()
new Promise((resolve, reject) => {
  const obj = {
    then(resolve, reject){
      resolve('success!!!')
    }
  }
  resolve(obj)
}).then(res => {
  console.log(res);
}, err => {
  console.log(err);
})

Promise对象方法~then

/**
 * then方法是Promise对象上的一个方法: 其实是放在Promise原型上的 Promise.prototype.then
 * const promise = new Promise()    promise.then()
 */
// console.log(Object.getOwnPropertyDescriptors(Promise.prototype))

const promise = new Promise((resolve, reject) => {
  resolve('success~~')
})

// 1.同一个Promise可以多次调用then方法,then方法都会被执行
// promise.then(res => {
//   console.log('res1:',res);
// })
// promise.then(res => {
//   console.log('res2:',res);
// })
// promise.then(res => {
//   console.log('res3:',res);
// })

// 2.then方法的res回调中,可以有返回值
// 1> 返回普通值,这个普通的值被作为一个新的Promise的resolve值
promise.then(res => {
  // 默认返回 undefined
  return 'aaaaaa'
  // 上面的等价于下面的
  // return new Promise(resolve => {
  //   resolve('aaaaaa')
  // })
}).then(res => {
  console.log(res) // aaaaa
  return 'bbbbbbb'
}).then(res => {
  // throw new Error('抛出异常!')
  // throw '错误!'
  console.log(res) // bbbbb
}).catch(err => {
  // console.log(err) // 错误
})

// 2> 返回一个Promise
promise.then(res => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('xxxxxxxxxx')
    }, 3000);
  })
}).then(res => {
  // 处理上面返回的Promise
  console.log(res);
})

// 3> 返回一个对象, 并且这个对象有实现then方法.
promise.then(res => {
  return {
    then(resolve, reject) {
      resolve('----------') // 有这个resolve决定
    }
  }
}).then(res => {
  console.log(res) // ----------
})

Promise对象方法~catch

const promise = new Promise((resolve, reject) => {
  resolve('success!')
  // reject('error~~~')
  // throw '错误!'
})

// 1.传入二个回调
// promise.then(undefined, err => {
//   console.log(err);
// })

// 2.语法糖写法
promise.then(res => {
  // throw '错误!'
  return new Promise((resolve, reject) => {
    reject('then err~')
  })
}).catch(err => {
  console.log(err)
})

// 3.catch()里返回普通值,这个普通的值被作为一个新的Promise的resolve值,被then()回调.
const p = new Promise((resolve, reject)=>{
  reject('errr')
})
p.catch(err => {
  return 'messages!!!'
}).then(res => {
  console.log('res:', res) // messages!!!
}).catch(err => {
  console.log('err:', err);
})

Promise对象方法~finally

/**
 * finally在ES9(ES2018)新增的特效: 包含finally,无论什么状态,最终都会执行的代码.(没有参数)
 */
const promise = new Promise((resolve, reject) => {
  resolve('success!')
})

promise.then(res => {
  console.log(res);
}).finally(()=>{
  console.log('我必执行~');
})

Promise类方法~resolve

// 类方法: Promise.resolve()
// 将 一个值或对象 转为 Promise

const promise = Promise.resolve({ name: 'Fhup' })
// 相当于下面的代码
// const p = new Promise((resolve, reject) => {
//   const obj = { name: 'Fhup' }
//   resolve(obj)
// })

promise.then(res => {
  console.log('res:', res)
})

// 对传入的值做出对应的处理 将状态进行了移交
const p = Promise.resolve(new Promise((resolve, reject)=>{resolve('----------')}))
p.then(res => {
  console.log('res:', res) // ----------
})

Promise类方法~reject

const promise = Promise.reject('err messages')
// 相当于
// const p = new Promise((resolve, reject) => {
//   reject('err mess')
// })

// Promise.reject()比较特殊,无论传入什么值都是err进行catch
promise.catch(err => {
  console.log('err:', err)
})

Promise类方法~all

/**
 * 执行完all里面的每个Promise,每个状态为fulfilled时才会拿到所有的结果.
 * 意外: 如果有一个reject,那么整个promise就是reject
 */
Promise.all([
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      resolve('aaaaaaaaa')
    }, 1000);
  }),
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      resolve('bbbbbbb')
      // reject('errrrrrrrrrrrr')
    }, 2000);
  }),
  '12323213123' // 普通的值也会转为Promise
]).then((res)=>{
  console.log(res)
}).catch(err => {
  console.log(err)
})

Promise类方法~allSettled

// allSettled不会去到catch中
Promise.allSettled([
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      resolve('aaaaaaaaa')
    }, 1000);
  }),
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      reject('errrrrrrrrrrrr')
    }, 2000);
  }),
]).then((res)=>{
  console.log(res)
})

// allSettled会执行完所有的Promise,执行完后的结果是个数组对象
// [
//   { status: 'fulfilled', value: 'aaaaaaaaa' },
//   { status: 'rejected', reason: 'errrrrrrrrrrrr' }
// ]

Promise类方法~race

/**
 * race: 竞赛/比赛
 * 只要有一个Promise变为fulfilled状态,就会结束.
 * 拿到第一个执行完的结果,作为then或catch的结果.
 */
Promise.race([
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      resolve('aaaaaaaaa')
    }, 1000);
  }),
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      reject('errrrrrrrrrrrr')
    }, 500);
  })
]).then(res => {
  console.log('res:', res);
}).catch(err => {
  console.log('err:', err);
})

Promise类方法~any

/**
 * ES12: 新增 Promise.any()
 * 至少拿到一个状态变为fulfilled时,才会结束.
 * 意外: 如果所有的Promise都是reject,等到所有的Promise变为rejected状态.
 */
Promise.any([
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      resolve('aaaaaaaaa')
      // reject('bbbbbbbbbb')
    }, 1000);
  }),
  new Promise((resolve, reject)=>{
    setTimeout(() => {
      reject('errrrrrrrrrrrr')
    }, 500);
  })
]).then(res => {
  console.log('res:', res)
}).catch(err => {
  console.log('err:', err) // err: [AggregateError: All promises were rejected]
  console.log(err.errors) // [ 'bbbbbbbbbb', 'errrrrrrrrrrrr' ]
})