实现一个简单的Promise

promise工作机制图解

我们可以在chrome开发工具下看下原生 promise 是什么:

new Promise((resolve, reject) => {})
return Promise {
[[PromiseStatus]]: "pending",  [[PromiseValue]]: undefined
}

可以看出Promise 实例有两个property,一个表示status一个为value

所以我们可以这样写Promise构造函数

var PENDING = 'pending'
var FULFILLED = 'resolved'
var REJECTED = 'rejected'

function MyPromise(fn) {
    if (typeof fn !== 'function') throw new TypeError('not a function')
    // init property
    this.status = PENDING
    this.value = undefined

    // 因为每当我们new Promise(fn) fn是立即执行的, 所以我们调用doHandle来处理fn,因为status一旦改变,就不能再变
    doHandle(this, fn)
}

我们写一个来处理fn 的函数,并控制逻辑

function doHandle(self, fn) {
    var done = false // 闭包
    fn(function(value) {
        if (done) return
        done = true
        // resolve
        resolve(self, value)
    }, function(reason) {
        if (done) return
        done = true
        // reject
        reject(self, reason)
    })
}

resolvereject 用来分别处理不同状态

function resolve(self, value) {
    try {
        self.status = FULFILLED 
        self.value = value
    } catch (e) {
        reject(self, e)
    }
}

function reject(self, reason) {
    self.status = REJECTED 
    self.value = reason
}

我们已经写好了promise 的状态改变,接下来完成 then 来完成异步操作

MyPromise.prototype.then = function(onFulFilled, onRejected) {
    var promise = new (this.constructor)(function() {})
    // 处理如何异步
    handle(this, onFulFilled, onRejected, promise)
    // chain object
    return promise
}

// 异步, most important
var immediateFn = (typeof setImmediate === 'function' && function(fn) { setImmediate(fn) }) || function(fn) {
    setTimeout(fn, 0)
}

function handle(self, onFulFilled, onRejected, promise) {
    immediateFn(function() {
        var cb = self.status === FULFILLED ? onFulFilled : onRejected
        if (cb === null) {
            (self.status=== FULFILLED ? resolve : reject)(promise, self.value)
            return
        }
        cb(self.value)
    })
}

好了,大功告成,可以Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值