七、Promise从0-1

62 阅读2分钟

1 为什么会出现

回调地狱:

     run(0)
      setTimeout(() => {
         run(1)
         setTimeout(() => {
            run(2)
         }, 500)
      }, 1000)

promise是es6中用来处理 异步操作的。如果不使用promise,就需要使用 回调函数。而如果需要多个有顺序的异步操作,就会造成回调地狱

2 promise的三种状态

pending: 待定的

fullfilled: 已解决,已实现

reject: 已拒绝,没有实现

image.png

3 基本使用

  let isRemeber = true
     let buyLv = new Promise((resolve, reject) => {
         if (isRemeber) {
             const lv = {
                 color: 'red',
                 price: '10000'
             }
             resolve(lv)
         } else {
             const err = new Error('加班忘了')
             reject(err)
         }
     })

    //  const test = function() {
    //     buyLv.then((res) => { // fullfiled
    //         console.log(res)
    //     }).catch(err => { // reject
    //         console.log(err.message)
    //     })
    //  }
    //  test()
    let isRemeber2 = true
     const buyLip = (res) => { 
         if (isRemeber2) {
            const lip = {
                brand: '阿玛尼',
                color: 'red'
            }
            const gift = `口红${lip.brand},LV包颜色${res.color}`
            return Promise.resolve(gift)
         } else {
            const err = new Error('包买了,口红因为加班忘了')
            return Promise.reject(err)
         }
     }
     
     const test2 = function() {
        buyLv
            .then(buyLip) // 买lv后才会去看有没有口红
            .then((res) => { // fullfiled
                console.log(res)
                console.log('同意恋爱')
            }) // 买口红后,则说明女生可以得到礼物
           .catch(err => { // reject
                console.log(err.message)
                console.log('拒绝恋爱')
            })
     }
     test2()

4 promise基本原理

function MyPromise(excutor) {
    self = this
    self.status = 'pending'
    self.value = null
    self.reason = null
    self.onFullfilledCallbacks = []
    self.onRejectedCallbacks = []

    // 2 添加resolve和reject方法
    function resolve(res) {
        if (self.status === 'pending') {
            self.value = res
            self.status = 'fullfilled'
            // 4 发布消息
            self.onFullfilledCallbacks.forEach(item => item(res))
        }
    }
    function reject(reason) {
        if (self.status === 'pending') {
            self.reason = reason
            self.status = 'rejected'
            // 4 发布消息
            self.onRejectedCallbacks.forEach(item => item(reason))
        }
    }
    // 1 先执行回调函数
    try{
        excutor(resolve, reject)
    } catch(err) {
        reject(err)
    }
}
// 链式没看懂****
MyPromise.prototype.then = function(onFullfilled, onRejected) {
    // 3 订阅消息
    onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : function(data) {console.log(data)}
    onRejected = typeof onRejected === 'function' ? onRejected : function(err) {throw err}
    let self = this
    // if (self.status === 'pending') {
    //     self.onFullfilledCallbacks.push(onFullfilled)
    //     self.onRejectedCallbacks.push(onRejected)
    // }
    // 5 实现链式调用
    if (self.status === 'fullfilled') {
        return new MyPromise((resolve, reject) =>{
            try {
                let x = onFullfilled(self.value)
                // 判断传进来的值是否是一个promise,是的话.then,否则resolve
                x instanceof MyPromise ? x.then(resolve, reject): resolve(x)
            } catch(err) {
                reject(err)
            }
        })
    }
    if (self.status === 'rejected') {
        return new MyPromise((resolve, reject) =>{
            try {
                let x = onRejected(self.reason)
                // 判断传进来的值是否是一个promise,是的话.then,否则resolve
                x instanceof MyPromise ? x.then(resolve, reject): resolve(x)
            } catch(err) {
                reject(err)
            }
        })
    }
    if (self.status === 'pending') {
        return new MyPromise((resolve, reject) => {
            self.onFullfilledCallbacks.push(() => {
                let x = onFullfilled(self.value)
                x instanceof MyPromise ? x.then(resolve, reject): resolve(x)
            })
            self.onRejectedCallbacks.push(() => {
                let x = onRejected(self.reason)
                x instanceof MyPromise ? x.then(resolve, reject): resolve(x)
            })
        })
    }
}
MyPromise.prototype.catch = function(fn) {
    this.then(null, fn)
}