美文网首页
promise的实现

promise的实现

作者: 静_summer | 来源:发表于2019-08-10 23:10 被阅读0次

1.规范:https://promisesaplus.com/

2.测试promise: https://www.npmjs.com/package/promises-aplus-tests

3.实现一个promise.all , promise.race, promise.finally


// all 接收一个promise数组,返回一个promise,并且是一个失败即失败,全成功才成功

  Promise.all = arr => {

    return new Promise((resolve, reject) => {

        let result = [], count = 0;

        for (let i = 0; i < arr.length; i++) {

            arr[i].then(val => {

                result[i] = val

                if(++count === arr.length) {

                    resolve(result)

                }

            }, reject)

        }

    })

  }

  // race 接收一个promise数组,返回一个promise,并且是一个失败即失败,一个成功即成功

  Promise.race = arr => {

    return new Promise((resolve, reject) => {

        let result = [];

        for (let i = 0; i < arr.length; i++) {

            arr[i].then(resolve, reject)

        }

    })

  }

// 不管成功还是失败都会执行

Promise.prototype.finally = fn => {

    return this.then(val => {

        fn()

    }, err => {

        fn()

    })

}

  1. 实现过程

const PENDING = 'pending'

const FUILFILLED = 'fulfilled'

const REJECTED = 'rejected'

function Promise(executor) {

    let self = this

    self.status = PENDING

    self.onFuilfilledCb = []

    self.onRejectedCb = []

    self.value = undefined

    self.reason = undefined

    function resolve(val) { // 2.1.2

        // setTimeout(() => {

            if (self.status === PENDING) {

                self.status = FUILFILLED

                self.value = val

                self.onFuilfilledCb.forEach(cb => cb(val))

            }

        // }, 0)

    }

    function reject (reason) { // 2.1.3

        // setTimeout(function(){

            if (self.status === PENDING) {

                self.status = REJECTED

                self.reason = reason

                self.onRejectedCb.forEach(cb => cb(reason))

            }

        // },0)

    }

    try{

        executor(resolve, reject)

    } catch (err) {

        reject(err)

    }

}

Promise.prototype.then = function (onFulfilled, onRejected) {

    onFulfilled = typeof onFulfilled === 'function'?onFulfilled:function(value){return  value};

    onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason};

    let self = this

    let promise2;

    if(this.status === FUILFILLED) {

        promise2 = new Promise((resolve, reject) => {

            setTimeout(() =>{

                try {

                    let x = onFulfilled(self.value)

                    resolvePromise(promise2, x, resolve, reject)

                } catch (err) {

                    reject(err)

                }

            }, 0)

        })

    }

    if(this.status === REJECTED) {

        promise2 = new Promise((resolve, reject) => {

            setTimeout(() =>{

                try {

                    let x = onRejected(self.reason)

                    resolvePromise(promise2, x, resolve, reject)

                } catch (err) {

                    reject(err)

                }

            }, 0)

        })

    }

    if(self.status === PENDING) {

        promise2 = new Promise((resolve, reject) => {

            self.onFuilfilledCb.push(() => {

                setTimeout(() => {

                    try {

                        let x = onFulfilled(self.value)

                        resolvePromise(promise2, x, resolve, reject)

                    } catch (err) {

                        reject(err)

                    } 

                }) 

            })

            self.onRejectedCb.push(() => {

                setTimeout(() => {

                    try {

                        let x = onRejected(self.reason)

                        resolvePromise(promise2, x, resolve, reject)

                    } catch (err) {

                        reject(err)

                    }

                })

            })

        })

    }

    return promise2

}

Promise.prototype.catch = function(onRejected) {

    this.then(null, onRejected)

}

Promise.deferred = Promise.defer = function(){

    let defer = {};

    defer.promise = new Promise(function(resolve,reject){

      defer.resolve = resolve;

      defer.reject = reject;

    });

    return defer;

  }

function resolvePromise(promise2, x, resolve, reject) {

    if(promise2 === x) {

        return reject(new TypeError('循环引用'))

    }

    let called = false

    if (x !== null && (typeof x === 'object' || typeof x === 'function')) { // 2.3.3

        try {

            let then = x.then

            if (typeof then === 'function') {

                then.call(x, y => {

                    if (called) return

                    called = true

                    resolvePromise(promise2, y, resolve, reject)

                }, err => {

                    if (called) return

                    called = true

                    reject(err)

                })

            } else {

                resolve(x)

            }

        } catch(err) {

            if (called) return

            called = true

            reject(err)

        }

    } else {

        resolve(x)

    }

}

Promise.resolve = function(value){

    return new Promise(function(resolve){

      resolve(value);

    });

  }

  //返回一个立刻失败的promise

  Promise.reject = function(reason){

    return new Promise(function(resolve,reject){

      reject(reason);

    });

  }

// mjs

module.exports = Promise;

相关文章

网友评论

      本文标题:promise的实现

      本文链接:https://www.haomeiwen.com/subject/pygdjctx.html