异步任务处理
- 通过回调函数,成功返回一个成功函数,失败返回一个失败函数
- 弊端:
- 自己封装的请求函数,需要设计好callback名称,使用很麻烦
- 使用别人封装的请求函数,需要阅读源码或文档,沟通成本较大
Promise
- Promiese是一个类
- 在通过new创建Promise时,需要传入一个回调函数(executor)
- 回调函数会立即执行,并且给传入另外两个回调函数resolve,reject
- 调用resolve时,会执行Promise对象的then方法传入的回调函数
- 调用reject时,会执行Promise对象的catch方法传入的回调函数
Promise对象方法
Promise.prototype
Executor
- 创建Promise时需要传入的一个回调函数,这个回调函数会立即执行,并且传入两个参数:resolve,reject
- 通常在Executor中确Promise的状态
- resolve()可以将pending => fulfilled
- reject()可以将pending => rejected
- 一但状态被确定下来,之后就不可以更改
resolve参数
- 传入普通值或者对象,这个值会作为then回调的参数
- 传入的是新的Promise,Promise的状态由新的Promise决定
- 传入的对象中含有then函数(实现了thenable接口),就会执行该then方法,Promise的状态由该then方法的结果来决定
then方法
- 是放在Promise的原型上的Promise.prototype.then
- 接收两个参数
- fulfilled的回调函数:状态变为fulfilled时回调
- rejected的回调函数:状态变为rejected时回调
- 一个Promise的then方法可以多次调用
- 每次调用都可以传入对应的fulfilled回调
- 当Promise的状态变成fulfilled时,这些回调函数都会被执行
- then方法返回值
- then方法本身有返回值,它的返回值是一个Promise,可以进行链式调用
- Promise有三种状态,then方法返回的Promise的状态
- 当then方法中的回调函数本身在执行的时候,那么它处于pending状态
- 当then方法中的回调函数返回一个结果时,那么它处于fulfilled状态,并且会将结果作为resolve的参数、
- 返回一个普通的值
- 返回一个Promise
- 返回一个thenable
- 当then方法发抛出一个异常时,那么它处于rejected状态
catch方法(ES6)
-
是放在Promise的原型上的Promise.prototype.catch
-
fulfilled和rejected都写在then方法中,阅读性太差。
-
ES6新增catch方法来传入reject的回调函数,但这种写法不符合 Promise/A+ 规范
-
一个Promise的catch方法可以多次调用
- 每次调用都可以传入对应的rejected回调
- 当Promise的状态变成rejected时,这些回调函数都会被执行
-
catch方法返回值
- catch方法本身有返回值,它的返回值是一个Promise,可以进行链式调用,后面继续用then或catch调用
- catch传入的回调函数在执行完之后,默认状态依然是fulfilled,会回调下一个then
- 如果希望执行后继续执行catch,需要抛出异常,就会回调下一个catch
finally方法(ES9)
- ES9新增,表示无论Promise对象变成fulfilled还是rejected状态,最终都会被执行的代码
- 不接收参数,不论什么状态都会执行
Promise类方法
Promise.prototype.constructor
resolve方法
-
Promise.resolve的用法相当于new Promise,并且执行resolve操作
-
将现有内容转成Promise对象
// 转成Promise对象 function toPromise() { const obj = { name: "zzy", }; return new Promise((resolve) => { resolve(obj); }); } toPromise().then((res) => { console.log(res); // { name: 'zzy' } }); // 类方法Promise.resolve // 1.传入普通的值 Promise.resolve({ name: "lll" }).then((res) => console.log(res)); // { name: 'lll' } // 相当于new Promise new Promise((resolve, reject) => { resolve({ name: "aaa" }); }).then((res) => console.log(res)); // { name: 'aaa' } // 2.传入Promise Promise.resolve( new Promise((resolve, reject) => { resolve("promise"); }) ).then((res) => console.log(res)); // 111 // 3.传入thenable Promise.resolve({ then(resolve, reject) { resolve("thenable"); }, }).then((res) => console.log(res)); // thenable
reject方法
-
reject方法类似resolve方法,只是会将Promise对象的状态设置为rejected状态
-
Promise.reject的用法相当于new Promise,并且执行reject操作
-
Promise.reject传入的参数无论是什么形态都不做处理,直接作为rejected的参数传递到catah
-
// 类方法Promise.reject // 无论传入什么值都一样 // 1.传普通值 Promise.reject("reject err").catch((err) => console.log(err)); // reject err // 相当于 new Promise((resolve, reject) => { reject("promise err"); }).catch((err) => console.log(err)); // promise err // 2.传入Promise Promise.reject(new Promise(() => {})).then( (res) => console.log(res, "res"), // 不会去回调resolve (err) => console.log(err, "err") ); // Promise { <pending> } err // 3.传thenable Promise.reject({ then(resolve, reject) { reject("thenable"); }, }).then( (res) => console.log(res, "res"), // 不会去回调resolve (err) => console.log(err, "err") ); // { then: [Function: then] } err
all方法
-
所有Promise都变成fulfilled时,再拿到结果
-
有一个Promise为rejected时,那么整个Promise为rejected
-
缺陷
- 有一个Promise为rejected时,那么整个Promise为rejected,对于resolved的和pending状态的Promise获取不到对应结果
-
// 创建多个Promise const p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("resolve1"); }, 1000); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => { resolve("resolve2"); }, 2000); }); const p3 = new Promise((resolve, reject) => { setTimeout(() => { reject("reject1"); }, 3000); }); // 所有Promise都变成fulfilled时,再拿到结果 Promise.all([p1, p2]).then((res) => console.log(res)); // 有1个Promise为rejected时,那么整个Promise为rejected Promise.all([p1, p3]).then( (res) => console.log(res), (err) => console.log(err) );
allSettled方法(ES11)
- ES11新增,Promise.allSettled会在所有的Promise(不论什么状态)都有结果(settled)时才会有最终状态
- 并且这个Promise的结果一定是fulfilled的
race方法
- 有一个Promise最先改变状态为fulfilled,直接返回结果,跳出执行
- 如果最先改变为rejected,则直接catch到reject的结果
any方法(ES12)
- 和race方法类似
- 至少有一个变为fulfilled,才会决定新Promise的状态
- 如果所有Promise都是reject,也会等到所有Promise变为rejected状态,会报错AggregateError
- err.errors
- 所有错误放到一个数组中返回
- new ArrayregateError(ES12)