一次搞定 promise

256 阅读3分钟

前言

本文主要讲了promise 是什么,解决了哪些问题,如何使用,以及如何实现一个简单的 promise。如果这些你都会的话,兄dei,点个赞再走哇。

很久很久以前

话说,在很久之前,那个时候天是蓝的,水是绿的,庄稼还是种在地里的。
我们处理网络请求时,是这样的。

请求1(function(请求结果1){
    请求2(function(请求结果2){
        请求3(function(请求结果3){
            ...
        })
    })
})

其实这样还好,除了可阅读性差、代码耦合度高、出现 bug 不容易定位之外,又不是不能用。不就 20 层回调么。直到有天,妹纸喊你下班看电影,你却因回调 bug 的缠身,省了一顿饭钱。痛定思痛,一定要解决这个回调地域。

Promise 的出现

那是一个夏天,“利奇马”台风刚过去的第二天。你网上学习了 Promise,过程中,有个非常奇妙的赶脚,痛并快乐着~,那天你知道了,Promise,它表示一个异步操作的最终状态(完成还是失败),以及该异步操作的结果值

  • Promise 的基本概念

Promise 的语法是这样的。

const myPromise = new Promise((resolve, reject) => {
  if ('success') {
    resolve('success')
  } else {
    reject('false')
  }
}

Promise 有三种状态:

pending:初始状态。  
fulfilled:表示异步操作成功,对应执行的是 resolve() 方法。  
rejected:表示异步操作失败,对应执行的是 reject() 方法。

Promise 对象原型上的方法有三个,then、catch、finally:

  • myPromise.then(myResolve, myReject):
1、then 方法是添加回调到当前的 promise (即:myPromise),返回一个新的 promise。
 当状态是 fulfilled 时,执行myResolve方法,参数是resolve() 方法传的参数。
 当状态是 rejected 时,执行myReject()方法,参数是reject() 方法传的参数。  
2、当使用 .then 链来调用时(.then().then()...),将以回调的返回值进行 resolve。  
3、需要注意的是 .then 方法中指定的方法是异步调用的。
  • myPromise.catch(reject):
1catch 方法只是 promise.then(myResolve, myReject); 方法的一个别名而已。
也就是说,这个方法用来注册当 promise 对象状态变为 Rejected 时 的回调函数。
2、需要注意的是,promise.then(myResolve).catch(myReject)的情况下,myResolve方法中的异常是可以在 catch 中捕获的。
  • myPromise.finally(onFinally):
不管 promise 的状态如何,都会执行的方法,在es2018中引入。才疏学浅,告辞。  

Promise 对象上的方法有四个:

  • Promise.resolve(): 接收参数的不同,会返回不同的 Promise 对象。
1、接收 promise 对象时,返回的还是接收到的 promise 对象。
2、接收 thenable 对象时,返回一个新的 promise 对象,这个对象有一个 .then 方法。
3、接收其他类型的参数时,返回一个将该参数作为值的新 promise 对象。
  • Promise.reject():
将接收到的值进行reject后,返回一个新的 promise 对象。
  • Promise.all():
1、接收一个由promise对象组成的数组,当该数组中所有promise都变成resolve时,该方法才会返回。
并将每个promise返回值组成一个数组作为成功回调的返回值。
2、当有一个promise对象reject时,promise.all()会立即停止,并将第一个reject的错误信息返回给新的promise对象。
  • Promise.race(): 返回一个新的promise对象。
参数promise数组中,有一个resolve或者reject,该函数会立即返回,并使用该promise对象进行resolve或者reject。

使用 promise

看了半天,头都昏咯,我只是想知道怎么用啊。你个糟老头子,用个给我看看先,你先实现一个睡觉函数。

const sleep = (time) => {
  return new Promise(resolve => setTimeout(() => resolve(), time))
}
console.log(new Date()) // Mon Aug 12 2019 22:56:26 GMT+0800 (中国标准时间)
sleep(2000).then(() => {
  console.log(new Date()) // Mon Aug 12 2019 22:56:28 GMT+0800 (中国标准时间)
})

好吧,蒜你有点东西。

实现一个promise

你这么厉害,咋不实现一个promise呢。 这个简单那,简单的 promise 还是可以蒙出来的。

未完,待续杯。。。