网路请求是一种异步事件。网络请求通常需要封装一个网络请求函数,这个函数需要传入 url 和 一个 回调函数,当网络请求成功后,将数据传入回调函数进行处理。但是这种方式对于复杂的网络请求,会出现回调地域。比如下面这个例子,每个网络请求函数的参数内部都有一个网络请求函数。这样的代码看起来复杂不易维护。

Promise 可以解决上面的回调地域问题,它是异步编程的一种解决方案。
1-Promise最基本的语法
通过 Promise 的源码,可以知道在 new Promise 创建对象的时候先是保存了一些状态信息 ,然后执行传入的函数,传入的函数是一个箭头函数,参数是 resolve 和 reject 函数,分别在网络请求成功和失败的时候调用
下面用一个setTimeout 来模仿异步请求的例子来看 Promise 最基本的语法。
1 | // 1.创建一个Promise对象 |
在创建Promise时,传入参数是箭头函数是固定的(一般我们都会这样写),resolve 和 reject 它们两个也是函数,通常情况下,我们会根据请求数据的成功和失败来决定调用哪一个。
如果是成功的,那么通常我们会调用 resolve(messsage) ,这个时候,我们后续的 then 会被回调。
如果是失败的,那么通常我们会调用 reject(error) ,这个时候,我们后续的 catch 会被回调。
2-Promise 三种状态

当我们开发中有异步操作时, 就可以给异步操作包装一个 Promise,异步操作之后会有三种状态
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
根据这三种状态 then() 里面可以传入两个参数,一个是 fulfill 状态执行的 resolve,一个是 reject 状态执行的 reject,这样不需要再使用 catch 去回调错误。比如可以将上面的例子改写成如下代码
1 | new Promise((resolve, reject) => { |
3-Promise链式调用
无论是 then 还是 catch 都可以返回一个Promise对象,因此,Promise 的代码可以进行链式调用
Promise.resovle():将数据包装成Promise对象,并且在内部回调resolve()函数
Promise.reject():将数据包装成Promise对象,并且在内部回调reject()函数
也就是 return new Promise(resolve => resolve(结果))
的简写为 return Promise.resolve(data)
,简写为 return data
1 | // 可以直接省略 Promise.resolve,直接 return 数据就可以 |
链式调用中对错误信息的处理
在链式调用中,哪一层 reject 之后,会直接执行catch,之后层就不会在执行。reject 的简写:
1 | // return Promise.reject('error message') |
4-Promise all() 的使用
如果我们有这样的需求,当两次异步请求完成了,才能进行一些操作。我们可以通过 Promise all() 方法来封装两次请求。
1 | // all([ , ]) 参数是一个数组,里面可以传入两个异步请求 |