promise的作用
当异步操作完成,我们需要调用回调传递完成结果
Promise可以表示异步操作完成的结果(一个或多个异步成功或失败),传入相应回调 (成功或失败时的回调)
promise的构成
Promise构造器(构造函数)的构成
- 构造器的方法用途主要分为两种
管理多个promise对象状态的方法:all,allSettled,race
直接生成非等待态的promise对象的方法 reject,resolve方法
promise对象的构成
promise对象的方法主要用途是=>传入并按照状态属性处理回调函数 (then ,catch , finally 等方法)
具有两个属性
new一个promise对象及立即执行
const promise1 = new Promise((resolve, reject) => { console.log('promise1') })
生成了promise1这个对象
new Promise需要传递一个执行器函数(executor) 这个函数默认就会立即执行,因此,打印出'promise1'字符串
promise对象
属性
1.PromiseStatus 状态
三个状态
默认 => pending 等待态
resolve(’string’) => fulfilled 成功态
reject(’string’) => rejected 失败态
如何改变状态
1.通过传入的状态参数改变
成功态
const promise = new Promise((resolve, reject) => {resolve('success');});
失败态
const promise = new Promise((resolve, reject) => {reject('success');});
##### 2.直接构造相应状态对象
>成功态
Promise.reject()
>失败态
Promise.resolve()
状态为fulfilled或rejected,可执行then方法
<br>一个promise对象状态一旦为fulfilled-成功态或rejected-失败态,不能再次被改变
### 2.PromiseValue 值
#### 如何改变值
##### 改变状态时传入
const promise = new Promise((resolve, reject) => {resolve('PromiseValue');});
Promise.reject('PromiseValue')
##### 调用方法的return
Promise.resolve('oldPromiseValue').then(res => {return 'newPromiseValue';})
## 方法
### then
每个promise的实例都具备一个then方法 then方法中传递两个参数
>1.成功的回调
<br>2.失败的回调
Promise . reject('err!!!’) .then((res) => { console.log('success', res) }, (err) => { console.log('error', err)})
### catch
catch(failureCallback)
是 then(null, failureCallback) 的缩略形式。
Promise . reject('err!!!’) .catch((err) => { console.log('error', err)})
===等价于===
Promise . reject('err!!!’) .then((res) => { console.log('success', res)}, (err) => { console.log('error', err) })
.then和.catch都会返回一个新的Promise对象
### then 和 catch 返回情况详解
我们把 then 和 catch 的返回分为以下三种情况这三种情况都会返回一个 promise 对象:
#### 回调函数不写return
>举个例子:
Promise.resolve(1).then(res => { console.log(res);})
打印出返回的promise对象
Promise {: undefined}
> 默认返回一个 promise 对象,该对象的状态由回调的执行结果确定 <br>
> 未执行pending,执行成功fulfilled,执行失败rejected
>该对象的值为undefined
#### return 了 promise 对象
>返回的 promise 对象就是 return 的 promise 对象
#### return 了非 promise 对象
> 回的promise 对象的值等于return 的内容 <br>
>promise 对象的属性依旧由回调完成情况决定
> 举个例子
Promise.resolve(1).then(res => {console.log(res);return 2;})
打印出返回的promise对象

> 和默认一样,返回一个 promise 对象,该对象的状态由回调的执行结果确定 <br>
> 未执行pending,执行成功fulfilled,执行失败rejected
>该对象的值为return 的内容
##### 容易混淆的例子
Promise.resolve().then(() => {return new Error('error!!!')})
会返回一个reject状态的 promise 吗?
return 后面是非promise 对象内容,因此
Promise {: Error: error!!! at :2:10}
返回一个状态为 resolved,值为error 报错的 promise对象
如果想通过return抛出异常,可以使用
return Promise.reject(new Error('error!!!’));
throw new Error(‘error!!!‘)
这两者都会返回一个异常 promise 对象(即对象状态为reject,对象值为报错信息的 promise 对象)
### finally
#### 无条件执行
> .finally()方法不管Promise对象最后的状态如何,都会执行
#### 不接受任何的参数
> .finally()方法方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise的状态是resolved还是rejected的,也不知道Promise的值
#### 返回值
##### 1.不抛出异常
> 默认返回是一个上一次的Promise对象值
Promise.resolve('2’) .finally(() => {return 'finally返回的值’ }) .then(res => { console.log('then', res) })
.finally里,返回值不会被return改变,返回是一个上一次的Promise对象的值

##### 2.抛出异常
> 如果抛出的是一个异常则返回异常的Promise对象
Promise.resolve(‘1’) .finally(() => { throw new Error(‘finally异常’) }) .catch(err => { console.log('捕获错误', err) })

----
# Promise构造函数
开头介绍过,构造器的方法用途主要分为两种 :
1. 管理多个 promise 对象状态的方法: all , allSettled , race
2. 直接生成非等待态的 promise 对象:reject , resolve
这里主要介绍管理多个 promise 对象状态的方法。
## 管理多个 promise 对象的方法
###用途
> 管理多个 promise 对象,通过返回的新 promise 对象,表示被管理的多个 promise 对象的执行结果<br>
> 会接上promise对象的方法(.then( ) .catch( ) .finally( ) ), 获取了多个 promise 执行状态后, 调用相应回调,如:
```js
Promise.all([promise1, promise2]).then(result => console.log(result));
.all( ) 和 .race( ) 方法
相同之处
. all( ) . race( ) 都接收一组 promise 对象(即 promise 对象构成的数组,如:
[promise1, promise2]
),并行执行 promise 对象的异步任务, 返回一个新的 promise 对象
即他们接收的参数相同,并且接收的参数的异步任务都会执行完成,不进行中断,并且都返回一个新的 promise 对象
不同之处
根据接收 promise 对象的参数的异步完成情况,返回的新 promise 对象状态不同
因此,我们可以通过.all( ) 和 .race( )返回的新 promise 对象状态,来了解他们的用法
通过例子,可以了解到返回的新 promise 对象的值
. all( )
- 返回的新 promise 状态为 resolve
接收的一组 promise 对象执行状态都变为 resolve
这意味着:
- 被管理的 promise 对象要全部执行完成
- 每个被管理的 promise 对象,执行结果都为成功态 resolve
- 返回的新 promise 状态为 reject
只要有一个接收的 promise 对象状态为 reject
这意味着:
- 被管理的 promise 对象不需要全部执行完成
- 至少有一个被管理的 promise 对象,执行结果为 reject
- 返回的新 promise 状态为 pedding
还在等待异步执行结果 这意味着:
- 被管理的 promise 对象没有全部执行完成
- 没有出现任何一个执行结果为 reject 的 promise 对象
例子
function runAsync (x) {
const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
return p
}
Promise.all([runAsync(1), runAsync(2), runAsync(3)])
.then(res => console.log(res))
runAsync
返回 promise 对象,该对象根据传入的参数x
, 在x秒后执行打印异步操作
根据参数,在1秒,2秒,3秒后异步尽快执行完成,按顺序打印出1,2,3,执行成功状态都为 resolve
.all( ) 返回状态为 resolve 的 promise 对象, 打印出返回的 promise 对象的值,即为被管理的 promise 对象的值,组成的数组
打印结果如下 :
返回的对象结构如图所示 :
. race( )
- 返回的新 promise 对象状态为 resolve
只要有一个被管理的 promise 对象状态为 resolve
这意味着:
- 有一个被管理的 promise 对象执行完成,状态为 resolve
- 其他的 promise 对象仍可以继续执行,不过执行结果对返回的新 promise 对象无影响
- 返回的新 promise 对象状态为 reject
只要有一个 promise 对象状态为 reject
这意味着:
- 有一个被管理的 promise 对象执行完成,状态为 reject
- 其他的 promise 对象仍可以继续执行,不过执行结果对返回的新 promise 对象无影响
- 返回的新 promise 状态为 pedding
还在等待异步执行结果 这意味着:
- 被管理的 promise 对象状态全为pedding
例子
function runAsync (x) {
const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
return p
}
Promise.race([runAsync(1), runAsync(2), runAsync(3)])
.then(res => console.log('race',res))
runAsync
返回 promise 对象,该对象根据传入的参数x
, 在x秒后执行打印异步操作
根据参数,在1秒,2秒,3秒后异步尽快执行完成
1秒后,打印出1
,执行成功状态为 resolve
.race( ) 返回状态为 resolve 的 promise 对象, 打印race 1
2秒,3秒后异步尽快执行完成,打印出2
, 3
打印结果如下 :
返回的对象结构如图所示 :
. allSettled( )方法
- 返回的新 promise 状态为 resolve
所有异步执行完成
这意味着:
- 被管理的 promise 对象要全部执行完成
- 被管理的 promise 对象,执行结果不为pendding
- 返回的新 promise 状态为 reject
不可能发生,除非灵异事件
- 返回的新 promise 状态为 pedding
还在等待异步执行结果 这意味着:
- 被管理的 promise 对象没有全部执行完成
- 没有出现任何一个执行结果为 reject 的 promise 对象
例子
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).then(result => console.log(result));
等 promise1 和 promise2异步执行完成后,打印出结果
打印结果如下 :
返回的对象结构如图所示 :
时序
1.promise对象方法建立微任务
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve('success')
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
Promise构造器立即执行,打印出
1
,将生产的promise对象状态设为resolve,值为success,再打印2
。
之后遇到promise对象的.then方法,因为状态非等待态,建立微任务队列。
打印4
执行微任务队列,打印3
2.和宏任务的比较
console.log('start');
setTimeout(() => {
console.log('time');
});
Promise.resolve().then(() => {
console.log('resolve');
});
console.log('end');
打印
start
,遇到 setTimeout ,建立宏任务
遇到resolve状态的promise对象的then方法,建立微任务
打印end
执行微任务队列,打印resolve
执行宏任务队列,打印end
链式调用
嗯,就是这样,不断返回promise对象,一直调用下去
值穿透
.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
将resolve(1) 的值直接传到最后一个then里,打印出
1