promise 术语
1 promise 是一个有then方法的对象或者函数,行为遵循PromiseA+规范
2 thenable 是一个有then方法的函数或者对象
3 value promise 状态成功时的值,resolve 的参数,number boolean undefined promise
4 reason promise 状态失败时的值, reject的参数
5 exception 异常值
promise的各种状态
1 pending
1.1 初始状态 可改变
1.2 一个promise在resolve或者reject之前都处于这个状态
1.3resolve: pending -> fufilled 状态
1.4reject: pending -> rejected 状态
2 fulfilled
2.1 最终态,不可变
2.2 一个promise被resolve后变成这个状态
2.3必须拥有一个value值
3 rejected
3.1 最终态,不可变
3.2 一个promise被reject后变成这个状态
3.3必须拥有一个reason值
** 总结:
pending -> resolve(value)->fullfilled
pending -> reject(reason)->rejected
**
then 函数
promise 应该提供一个then方法,用来访问最终的结果
promise.then(onFullfilled,onRejected)
1 参数要求
1.1 onFullfilled 必须是一个函数类型,如果不是函数,应该被忽略
1.2 onRejected必须是一个函数类型,如果不是函数,应该被忽略、
2 onFullfilled 特性
2.1 promise 变成fulfilled时,应该调用onFullfilled,参数是value
2.2 promise变成fulfilled之前,不应该被调用
2.3 只能被调用一次
3 onRejected特性
3.1 promise 变成rejected时,应该调用onRejected,参数是reason
3.2 promise变成rejected之前,不应该被调用
3.3 只能被调用一次
4 onFullfilled 与onRejected执行环境应该是微任务里
5 then方法可以被调用多次
const promise =new Promise();
promise.then(cb1,cb2)
promise.then(cb1,cb2)
promise.then(cb1,cb2)
promise.then(cb1,cb2)
5.1 promise状态变成fulfilled后,所有的onFulfilled回调都需要按照.then的顺序执行
5.2 promise状态变成rejected后,所有的onRejected回调都需要按照.then的顺序执行
6 then的返回值是promise,是个新的promise
const promise = new Promise();
const promise2 = promise.then(cb1,cb2)
6.1 onFulfilled 或者 onRejected执行结果为x,调用resolvePromise()
6.2 onFulfilled 或者onRejected执行的时候报错了,promise2就需要被reject
6.3 onFulfilled 不是一个函数,promise2以promise1的value,触发fulfilled
6.4 onRejected不是一个函数,promise2以promise1的reason,触发rejected
7 resolvePromise
resolvePromise(promise2,x,resolve,reject)
7.1 promise2=== x ,reject typeError
7.2 如果x是一个promise
peding
fulfilled
rejected
7.3 object/function
let then=x.then
then如果是一个函数,then.call(x) => x.then
实现一个promise
1 初始化class
class MyPromise {
constructor(){
}
}
2 定义三种状态类型
const PENDING ='pending'
const FULFILLED ='fulfilled'
const REJECTED = 'rejected'
3 设置初始状态
class MyPromise {
constructor(){
this.status= PENDING
this.value =null
this.reason =null
}
}
4 resolve/reject
1 更改status,pending ->fulfilled/rejected
2 入参value/reason
class MyPromise {
constructor(){
this.status= PENDING
this.value =null
this.reason =null
}
resolve(value){
if(this.status===PENDING ){
this.value = value
this.status = FULFILLED
}}
reject(reason){
if(this.status===PENDING ){
this.reason= reason
this.status = REJECTED
}
}
}
5 promise构造函数的入参
new Promise((resolve,reject))=>{}
1 入参是一个函数,函数接收两个参数,resoleve,reject
2 new Promise的时候就要执行这个函数,并且有任何错误都要被reject出去
class MyPromise {
FULFILLED_CALLBACK_LIST = []
REJECTED_CALLBACK_LIST = []
_status ='pending'
constructor(fn){
this.status= PENDING
this.value =null
this.reason =null
try{
fn(this.resolve.bind(this),this.reject.bind(this))
}catch(e){
this.reject(e)
}
}
get status(){
return this._status
}
set status(newStatus){
this._status = newStatus
switch(newStatus){
case FULFILLED:{
this.FULFILLED_CALLBACK_LIST.forEach((callback)=>{
callback(this.value)
})
break:
}
case REJECTED:{
this.REJECTED_CALLBACK_LIST.forEach((callback)=>{
callback(this.reason)
})
break:
}
}
}
resolve(value){
if(this.status===PENDING ){
this.value = value
this.status = FULFILLED
}}
reject(reason){
if(this.status===PENDING ){
this.reason= reason
this.status = REJECTED
}
}
})
return promise2
}
isFunction(param){
return typeof param === 'function'
}
}
6 then函数,catch函数
then(onFullfilled,onRejected){
const realOnFulfilled = this.isFunction(onFullfilled)? onFullfilled :(value)=>{
return value
}
const realOnReject = this.isFunction(onRejected)? onRejected:(reason)=>{
throw reason
}
const promise2 = new MPromise((resolve,reject)=>{
const fulfilledMicrotask=()=>{
queueMicrotask(()=>{
try{
const x = realOnFulfilled (thia.value)
this.resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
}
const rejectedMicrotask=()=>{
queueMicrotask(()=>{
try{
const x=realOnReject (thia.reason)
this.resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
}
switch(this.status) {
case FULFILLED :{
fulfilledMicrotask();
break:
}
case REJECTED :{
rejectedMicrotask();
break:
}
case PENDING:{
this.FULFILLED_CALLBACK_LIST .push(fulfilledMicrotask)
this.REJECTED_CALLBACK_LIST .push(rejectedMicrotask)
}
}
// catch 函数
catch(onRejected){
return this.then(null,onRejected)
}
7 resolvePromise函数
resolvePromise(promise2,x,resolve,reject){
if(promise2===x){
return reject(new TypeError('The promise and the return value are the same'))
}
if(x instanceof MPromise){
queueMicrotask(()=>{
x.then((y)=>{
this.resolvePromise(promise2,y,resolve,reject)
}),
reject
})
}else if(typeof x === 'object'|| this.isFunction(x)){
if(x===null){
return resolve(x)
}
let then = null
try{
then = x.then;
} catch(error){
return reject(error)
}
if(this.isFunction(then)){
let called = false
try{
then.call(x,(y)=>{
if(called ){
return;
}
called=true
this.resolvePromise(promise2,y,resolve,reject)
},(r)=>{
if(called ){
return;
}
called=true
reject(r)
})
}catch(error){
if(called ){
return;
}
reject(error)
}
}else{
resolve(x)
}
}else{
resolve(x)
}
}