ES6-22 手写实现之『ES6 Promise』

doSth().then(function(data){
    console.log(data) // 10
})
function doSth(){
    let data = 10
    return {
        then(callback){
            callback(data)
        }
    }
}
function doSth() {
    let data = 30
    return new Promise(function (resolve) {
        resolve(data)
    })
}
function Promise(executor) {
    let callback
    function resolve(data) {
        setTimeout(() => {
            callback(data)
        })
    }
    function reject(err) {
        setTimeout(() => {
            callback(err)
        })
    }
    this.then = function (cb) {
        callback = cb
    }
    executor(resolve, reject)

}
doSth().then((data) => {
    console.log(data)
})
  • resolve方法将外部data保存给Promise的value
  • 用handle函数来处理.then的cb和value
  • 有处理.then回调函数的方法
function doSth() {
    let data = 40
    return new Promise(function (resolve) {
        resolve(data)
    })
}
function Promise(executor) {
    let state = 'pending'
    let value
    function resolve(newVal) {
        state = 'resolved'
        value = newVal
    }
    function reject(err) {
    }
    function handle(onResolved){
        onResolved(value)
    }
    executor(resolve, reject)
    this.then = function (onResolved) {
        handle(onResolved)
    }
}
doSth().then((data) => {
    console.log(data)
})
  • 链式调用,需要.then返回promise
  • handle方法接收对象,保存resolve和cb
  • 实例化promise,value第一次更新
  • 每一次调用.then,.then的cb的返回值再次更新value
  • .then时不传cb,不会对value有动作,继续将这个value resolve下去
function doSth() {
    let data = 10
    return new Promise((resolve, reject) => {
        resolve(data)
    })
}
function Promise(executor) {
    let callback,
        value
    let state = 'pending'
    function resolve(data) {
        value = data
        state = 'resolved'
    }
    function reject() {

    }
    function handle(handler) {
        if(!handler.cb){
            handler.resolve(value)
            return
        }
        let res = handler.cb(value)
        handler.resolve(res)
    }
    executor(resolve)
    this.then = (cb) => {
        return new Promise(function (resolve) {
            handle({
                resolve,
                cb
            })
        })
    }

}
doSth()
    .then((data) => {
        console.log('p1', data)
        return 20
    })
    .then()
    .then((data) => {
        console.log('p2', data)
    })
  • 某次.then调用中,返回了promise
function doSth() {
    let data = 10
    return new Promise((resolve, reject) => {
        resolve(data)
    })
}
function doSth2(data) {
    console.log('doSth2', data) // 20
    return new Promise((resolve) => {
        resolve(data)
    })
}
function Promise(executor) {
    let callback,
        value
    let state = 'pending'
    function resolve(data) {
        value = data
        state = 'resolved'
    }
    function reject() {

    }
    function handle(handler) {
        if (!handler.cb) {
            handler.resolve(value)
            return
        }
        let res = handler.cb(value)
        handler.resolve(res)
    }
    executor(resolve)
    this.then = (cb) => {
        return new Promise(function (resolve) {
            handle({
                resolve,
                cb
            })
        })
    }

}
doSth()
    .then((data) => {
        console.log('p1', data) // p1 10
        return 20
    })
    .then((data) => {
        return doSth2(data)
    })
    .then((data) => {
        console.log('promise', data)
        data.then((data) => {
            console.log('p2', data) // p2 20
        })
    })
  • 优化
  • .then里递归resolve
function doSth() {
    let data = 10
    let state = 'pending'
    return new Promise((resolve, reject) => {
        resolve(data)
    })
}
function doSth2(data) {
    console.log('doSth2', data) // 20
    return new Promise((resolve) => {
        resolve(data)
    })
}
function Promise(executor) {
    let callback,
        value
    function resolve(data) {
        if (data instanceof Promise) {
            console.log('返回的是promise', data.then(resolve))
        } else {
            value = data
        }
        state = 'resolved'
    }
    function reject() {

    }
    function handle(handler) {
        if (!handler.cb) {
            handler.resolve(value)
            return
        }
        let res = handler.cb(value)
        handler.resolve(res)
    }
    executor(resolve)
    this.then = (cb) => {
        return new Promise(function (resolve) {
            handle({
                resolve,
                cb
            })
        })
    }

}
let promise3 = doSth()
doSth()
    .then((data) => {
        console.log('p1', data) // p1 10
        return 20
    })
    .then((data) => {
        return doSth2(data)
    })
    .then((data) => {
        console.log('promise2', data)
    })
  • 失败的回调
  • 成功还是失败是在doSth里决定的
  • 改造.then
  • 改造handle
function doSth() {
    return new Promise((resolve, reject) => {
        let reason = '手动失败'
        reject(reason)
    })
}

function Promise(executor) {
    let callback,
        value,
        state = 'pending'
    function resolve(data) {
        if (data instanceof Promise) {
            console.log('返回的是promise', data.then(resolve))
        } else {
            value = data
        }
        state = 'resolved'
    }
    function reject(reason) {
        state = 'rejected'
        value = reason
    }
    function handle(handler) {
        let handlerCallback
        if (state === 'resolved') {
            handlerCallback = handler.cb
        } else {
            handlerCallback = handler.cbReject
        }
        if (!handlerCallback) {
            if (state === 'resolved') {
                handler.resolve(value)
            } else {
                handler.reject(value)
            }
            return
        }
        let res = handlerCallback(value)
        handler.resolve(res)
    }
    executor(resolve, reject)


    this.then = (cb, cbReject) => {
        return new Promise(function (resolve, reject) {
            handle({
                cb,
                resolve,
                cbReject,
                reject,
            })
        })
    }

}
let promise3 = doSth()
doSth()
    .then((data) => {
        console.log('p1', data) 
        return 20
    }, (err) => {
        console.log('err', err) // err 手动失败
    })
  • 优化
  • 对内部resolve做异常处理 try…catch
  • 对.then的handlerCallback(value)做异常处理
  • promise应当是异步的:用定时器包裹handle
function doSth() {
    return new Promise((resolve, reject) => {
        let reason = '手动失败'
        reject(reason)
    })
}

function Promise(executor) {
    let callback,
        value,
        state = 'pending'
    function resolve(data) {
        try {
            if (data instanceof Promise) {
                console.log('返回的是promise', data.then(resolve))
            } else {
                value = data
            }
            state = 'resolved'
        } catch (e) {
            reject(e)
        }
    }
    function reject(reason) {
        state = 'rejected'
        value = reason
    }
    function handle(handler) {
        setTimeout(() => {
            let handlerCallback
            if (state === 'resolved') {
                handlerCallback = handler.cb
            } else {
                handlerCallback = handler.cbReject
            }
            if (!handlerCallback) {
                if (state === 'resolved') {
                    handler.resolve(value)
                } else {
                    handler.reject(value)
                }
                return
            }
            let res
            try {
                res = handlerCallback(value)
            } catch (e) {
                reject(e)
                return
            }
            handler.resolve(res)
        });

    }
    executor(resolve, reject)


    this.then = (cb, cbReject) => {
        return new Promise(function (resolve, reject) {
            handle({
                cb,
                resolve,
                cbReject,
                reject,
            })
        })
    }

}
let promise3 = doSth()
console.log(1)
doSth()
    .then((data) => {
        console.log('p1', data)
        return 20
    }, (err) => {
        console.log('err', err) // err 手动失败
    })
console.log(2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值