用TypeScript手写Promise实现源码

TS源码:

class Promise2 {
    state = 'pending'
    callbacks= []

    resolve(result) {
        setTimeout(()=>{
            if (this.state !=='pending') return
            this.state = 'fulfilled'
            this.callbacks.forEach((handle)=>{
                if (typeof handle[0] === "function") {
                    handle[0].call(undefined, result)
                }
            })
        },0)
    }

    reject(reason) {
        setTimeout(()=>{
            if (this.state !== 'pending') return
            this.state = 'rejected'
            this.callbacks.forEach((handle)=>{
                if (typeof handle[1] === "function") {
                    handle[1].call(undefined, reason)
                }
            })
        },0)
    }

    constructor(fn) {
        if (typeof fn !== "function") {
            throw new Error('我只接受一个函数')
        }
        fn(this.resolve.bind(this), this.reject.bind(this))
    }

    then(succeed?, fail?) {
        const handle = [];// 成功与失败的处理器
        if (typeof succeed === "function") {
            handle[0] = succeed
        }
        if (typeof fail === "function") {
            handle[1] = fail
        }
        this.callbacks.push(handle)
        //then后面需要return一个promise,后续补充
        return undefined
    }
}

export default Promise2

 

测试代码:

import * as chai from 'chai'
import * as sinon from 'sinon'
import * as sinonChai from 'sinon-chai'
chai.use(sinonChai)

const assert = chai.assert
import Promise from '../src/index'

describe('Promise', ()=> {
    it('是一个类', () => {
        assert.isFunction(Promise)
        assert.isObject(Promise.prototype)
    });
    it('new Promise() 如果不接受一个函数就报错', () => {
        // assert.throw(fn)的用法:期待报错
        assert.throw(()=> {
            // @ts-ignore
            new Promise()
        })
        assert.throw(()=> {
            // @ts-ignore
            new Promise(1)
        })
        assert.throw(()=> {
            // @ts-ignore
            new Promise(true)
        })
    });
    it('new Promise(fn) 会生成一个对象,对象有then方法', () => {
        const promise = new Promise(()=> {})
        assert.isFunction(promise.then)
    });
    it('new Promise(fn) 中的 fn 立即执行', () => {
        let fn = sinon.fake()
        new Promise(fn)
        assert(fn.called)
    });
    it('new Promise(fn) 中的fn执行时接收resolve和reject两个函数', () => {
        new Promise((resolve, reject)=>{
            assert.isFunction(resolve)
            assert.isFunction(reject)
        })
    });
    it('promise.then(success) 中的 success 会在 resolve 被调用的时候执行', (done) => {
        const fn = sinon.fake()
        const promise = new Promise((resolve, reject)=>{
            assert.isFalse(fn.called)
            resolve()
            setTimeout(()=>{
                assert.isTrue(fn.called)
                done()
            },0)
        })
        // @ts-ignore
        promise.then(fn)
    });
    it('promise.then(null, fail) 中的 fail 会在 reject 被调用的时候执行', (done) => {
        const fn = sinon.fake()
        const promise = new Promise((resolve, reject)=>{
            assert.isFalse(fn.called)
            reject()
            setTimeout(()=>{
                assert.isTrue(fn.called)
                done()
            },0)
        })
        // @ts-ignore
        promise.then(null, fn)
    });
    it('2.2.1 then的两个参数:onFulfilled和onRejected都是可选参数', () => {
        const promise = new Promise(resolve=> {
            resolve()
        })
        promise.then(false, null)
        assert(1 === 1)
    });
    it('2.2.2 如果onFulfilled是函数', (done) => {
        const succeed = sinon.fake()
        const promise = new Promise(resolve=>{
            assert.isFalse(succeed.called)
            resolve(789);
            resolve(999)
            setTimeout(()=>{
                assert(promise.state === 'fulfilled')
                assert.isTrue(succeed.calledOnce)// 期待函数传值不会超过一次
                assert(succeed.calledWith(789))// 期待succeed被called的时候resolve传了一个参数
                done()
            }, 0)
        })
        promise.then(succeed)
    });
    it('2.2.3 如果onRejected是函数', (done) => {
        const fail = sinon.fake()
        const promise = new Promise((resolve, reject)=>{
            assert.isFalse(fail.called)
            reject(789);
            reject(999)
            setTimeout(()=>{
                assert(promise.state === 'rejected')
                assert.isTrue(fail.calledOnce)// 期待函数传值不会超过一次
                assert(fail.calledWith(789))// 期待fn被called的时候resolve传了一个参数
                done()
            }, 0)
        })
        promise.then(null, fail)
    });
    it('2.2.4 在我的代码执行完前,不得调用then后面的两个函数', (done) => {
        const fn = sinon.fake()
        const promise = new Promise((resolve, reject)=>{
          resolve()
        })
        promise.then(fn)
        assert.isFalse(fn.called)// 在执行完fn.called后才调用then后面的函数
        setTimeout(()=>{
            assert.isTrue(fn.called)
            done()
        }, 0)
    });
    it('2.2.4 失败回调', (done) => {
        const fn = sinon.fake()
        const promise = new Promise((resolve, reject)=>{
            reject()
        })
        promise.then(null, fn)
        assert.isFalse(fn.called)// 在执行完fn.called后才调用then后面的函数
        setTimeout(()=>{
            assert.isTrue(fn.called)
            done()
        }, 0)
    });
    it('2.2.5 期待this上下文环境被promise传递', () => {
        const promise = new Promise((resolve, reject)=>{
            resolve()
        })
        promise.then(function () {
            'use strict'
            assert(this === undefined)
        })
    });
    it('2.2.6 then可以在同一个promise里被调用多次(成功)', (done) => {
        const promise = new Promise((resolve, reject)=>{
            resolve()
        })
        const callBacks = [sinon.fake(), sinon.fake(), sinon.fake()]
        promise.then(callBacks[0])
        promise.then(callBacks[1])
        promise.then(callBacks[2])
        setTimeout(()=>{
            assert(callBacks[0].called)
            assert(callBacks[1].called)
            assert(callBacks[2].called)
            assert(callBacks[1].calledAfter(callBacks[0]))// 期待函数[1]在函数[0]之后调用
            assert(callBacks[2].calledAfter(callBacks[1]))// 期待函数[2]在函数[1]之后调用
            done()
        }, 0)
    });
    it('2.2.6.2 then可以在同一个promise里被调用多次(失败)', (done) => {
        const promise = new Promise((resolve, reject)=>{
            reject()
        })
        const callBacks = [sinon.fake(), sinon.fake(), sinon.fake()]
        promise.then(null, callBacks[0])
        promise.then(null, callBacks[1])
        promise.then(null, callBacks[2])
        setTimeout(()=>{
            assert(callBacks[0].called)
            assert(callBacks[1].called)
            assert(callBacks[2].called)
            assert(callBacks[1].calledAfter(callBacks[0]))// 期待函数[1]在函数[0]之后调用
            assert(callBacks[2].calledAfter(callBacks[1]))// 期待函数[2]在函数[1]之后调用
            done()
        }, 0)

    });
})

 

你可能感兴趣的:(JS)