Promise用法总结

174 阅读3分钟

【前言】

处在前后端分离开发模式的时代,前端向后端请求数据似乎已经司空见惯,在稍微复杂一点的业务中就可能遇到串行接口的情况,这就会产生回调嵌套,回调过深会导致代码可维护性差,因此需要一种解决回调过深的方案:promise。ES6 promise语法精深,本文只介绍工作中最常用到的promise相关知识。

【目录】

  1. Promise 的用途
  2. 如何创建一个 new Promise
  3. 如何使用 Promise.prototype.then
  4. 如何使用 Promise.all
  5. 如何使用 Promise.race

【正文】

1.Promise 的用途

  1. 规范回调的名字和顺序
  2. 拒绝回调地狱,让代码可读性更强
  3. 很方便的捕获错误

2. 如何创建一个 new Promise

var promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

3. 如何使用 Promise.prototype.then

虽然then方法接受两个函数作为参数,但一般只写成功回调,并用catch代替失败回调

//bad
promise.then(successFn,errorFn)
//good
promise.then(successFn).catch(errorFn)

let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
  reject('失败了')
})

p1.then((result) => {console.log(result)}).catch((result) => {console.log(result)})

4. 如何使用 Promise.all

Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。

let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
  resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})

Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}

let p1 = wake(3000)
let p2 = wake(2000)

Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})

需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

5. 如何使用 Promise.race

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})

Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打开的是 'failed'
})