Promise浅浅理解(PENDING(等待),FULFILLED(成功),REJECTED(失败)三个状态)

256 阅读2分钟
  • promise浅浅理解
let p1 = new Promise((resolve, reject) => {
    resolve('成功')
})

promise是一个构造函数

promise是一个构造函数,我们需要使用new关键字来调用,
        constructor(accept) { 
            const resolve = (value) => {}
                const reject = (reason) => {}
                        accept(resolve, reject)
       }
 }
内部接收一个回调函数,(这里用accept),内部有两个参数resolve,reject分别为两个回调函数,各携带一个参数

promise状态变更

let p = new Promise((resolve,reject) => 
{
    resolve('ok')
    reject('no')
})

p.then(
        (value) => {
            console.log(value)  //ok
},
        (err) => {
             console.log(err)
}
)
let p1 = new Promise((resolve,reject) => 
{
    resolve('ok')
    reject('no')
})

p.then(
        (value) => {
            console.log(value)
},
        (err) => {
             console.log(err)  //err
}
)

通过代码,看到promise返回的是一个实例,带有then方法且then方法中带有2个回调函数,可以通过回调获取参数,我们便可以通过resolve和reject函数获取结果,promise会通过resolve,reject确定状态,一旦确定好状态,就只执行对应的回调函数,忽略其他的resolve或者reject

所以我们需要指定状态,储存resolve和reject 的值,传递给then

const [PENDING, FULFILLED, REJECTED] = ['PENDING', 'FULFILLED', 'REJECTED']
class MyPromise { 
    constructor(accept) {
        this.status = PENDING 
        this.value = undefined 
        this.reason = undefined 
        const resolve = (value) => {
            if (this.status === PENDING) { 
                this.status = FULFILLED 
                this.value = value
            } 
        }
        const reject = (reason) => { 
            if (this.status === PENDING) { 
                this.status = REJECTED 
                this.reason = reason 
            } 
        } 
        accept(resolve, reject) 
} 
        then(onFulfilled, onRejected) { 
            if (this.status === FULFILLED) {
                onFulfilled(this.value) 
            } 
            if (this.status === REJECTED) {
                onRejected(this.reaosn)
            } 
    } 
}


先声明promise的PENDING(等待),FULFILLED(成功),REJECTED(失败)三个状态,来记录promise的状态,根据resolve和reject来修改状态,把值存储起来,在then回调中执行对应的函数

promise 异步

const [PENDING, FULFILLED, REJECTED] = ['PENDING', 'FULFILLED', 'REJECTED'] 
class MyPromise {
    constructor(accept) {
        this.status = PENDING
        this.value = undefined 
        this.reason = undefined 
        const resolve = (value) => {
            if (this.status === PENDING) {
                this.status = FULFILLED 
                this.value = value
                this.onFulfilled && this.onFulfilled(value) 
            } 
        }
        const reject = (reason) => {
            if (this.status === PENDING) { 
                this.status = REJECTED 
                this.reason = reason 
                this.onRejected && this.onRejected(reason)
            } 
        }
       accept(resolve, reject) 
} 
 then(onFulfilled, onRejected) { 
    if (this.status === FULFILLED) { 
        onFulfilled(this.value) 
    } 
    if (this.status === REJECTED) {
        onRejected(this.reaosn) 
    } 
    if (this.status === PENDING) { 
            // 存储回调函数 
        this.onFulfilled = onFulfilled 
        this.onRejected = onRejected 
    } 
  }
}

promise的padding状态下将then的回调存储,在status改变状态后执行达到异步效果

then微任务

let p1 = new Promise((resolve, reject) => {
                resolve('成功') 
             })
p1.then((value) => console.log(value)) console.log(11) 

// 11 => 成功

以及promise的知识我们应该知道then的回调函数实际是将这个回调加入到了微任务队列中 所以先打印11 然后再打印成功,而我们的代码却并是同步执行

then(onFulfilled, onRejected) { 
        if (this.status === FULFILLED) { 
            setTimeout(() => { 
                onFulfilled(this.value) 
            }) 
        } 
        if (this.status === REJECTED) {
           setTimeout(() => { 
               onRejected(this.reason) 
           }) 
       } 
       if (this.status === PENDING) { 
              this.onFulfilled = onFulfilled 
              this.onRejected = onRejected 
       } 
   }

我们需要将then的回调函数模拟微任务的形式,这里我们使用setTimeout来模拟微任务

Promise缺点:

无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
当处于 Pending 状态时,无法得知目前进展到哪一个阶段。

try catch

let p1 = new MyPromise((resolve, reject) => { 
                throw new Error('err') 
})
p1.then( (value) => { 
    console.log(value, 111) 
}, 
(err) => {
    console.log(err)
    } 
)

try {
    accept(resolve, reject)
} catch (e) {
    reject(e)
}