博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自己照着Promise/A规范写的Promise库
阅读量:5825 次
发布时间:2019-06-18

本文共 8021 字,大约阅读时间需要 26 分钟。

试图写了一下,大概测试了一下,没有用专业的测试工具测试....

代码感觉还是写的比较好懂的,本人水平较差,如果测试有问题,欢迎回复指出

地址:

(function(global) {    function isFunction(val) {        return typeof val == 'function';    }    function isObject(val) {        return typeof val == 'object';    }    function asyncExcute(fn) {        return function() {            setTimeout(fn); // 同一执行队列中,原生Promise是先于setTimeout实现的,自己实现暂时用setTimeout模拟        }    }    function Promise(fn) {        if (!isFunction(fn) || this instanceof Promise == false) {            throw new TypeError("Promise必须传入function并且new构造")        }        this.status = 'pending';        this.value = undefined; //  promise状态改变之后传递的值        this.thenPromise = undefined; //执行then之后返回的promise        this.resolveQueue = []; //        this.rejectQueue = []; //           var re = asyncExcute(function(resolveData) { this._resolve(resolveData) }.bind(this)), //这里必须异步处理,否则then函数执行以前可能就已经执行了_resolve,但这时then中函数还未加入resolveQueue中            rj = asyncExcute(function(resolveData) { this._reject(resolveData) }.bind(this));        try {            fn(re, rj)        } catch (error) {            this.status = 'reject';            this.value = error;            asyncExcute(function(){this._reject(error)});         //  new Promise(()=>{ 出现异常... }).then(refn,rjfn);    出现异常时then还未执行, rjfn还未加入到rejectQueue中          }    }    Promise.prototype.then = function(refn, rjfn) {        var returnPro = new Promise(function() {});        this.thenPromise = returnPro;        this.resolveQueue.push(refn);        this.rejectQueue.push(rjfn);        if (this.status == 'resolve') { //执行then时,如果状态已经不是pending,则执行相应函数            this._resolve(this.value);        }        if (this.status == 'reject') {            this._reject(this.value);        }        return returnPro;    }    Promise.prototype._resolve = function(resolveData) {        var handle,            returnVal;        this.status = "resolve";        this.value = resolveData;        while (this.resolveQueue.length > 0) { //2.2.6  当 promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调            handle = this.resolveQueue.shift();            if (!isFunction(handle)) { //不是函数  2.1.1 onFulfilled 不是函数,其必须被忽略                this.thenPromise.value = resolveData;                this.thenPromise.status = 'resolve';                this.thenPromise._resolve();                return;            }            try { //如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e                returnVal = handle(resolveData);            } catch (error) {                this.thenPromise.status = 'reject';                this.thenPromise.value = error;                this.thenPromise._reject();            }            if (isObject(returnVal || isFunction(returnVal))) { //如果返回值为对象或者函数                if (returnVal == this.thenPromise) { //如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise                    this.thenPromise.status = 'reject';                    this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一对象');                } else if (returnVal instanceof Promise) { //如果 x 为 Promise ,则使 promise 接受 x 的状态                    try {                        then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));                    } catch (error) {                        this.thenPromise.status = 'reject';                        this.thenPromise.value = error;                        this.thenPromise._reject();                    }                } else { //如果 x 为对象或者函数                    try { //如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise                        var then = returnVal.then;                        if (isFunction(then)) {                            then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));                        }                    } catch (error) {                        this.thenPromise.status = 'reject';                        this.thenPromise.value = error;                        this.thenPromise._reject();                    }                }            } else {                this.thenPromise.value = returnVal;                this.thenPromise.status = 'resolve';                this.thenPromise._resolve();            }        }    }    Promise.prototype._reject = function(resolveData) {        var handle,            returnVal;        this.status = "resolve";        this.value = resolveData;        while (this.rejectQueue.length > 0) {     //2.2.6  当 promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调            handle = this.rejectQueue.shift();            if (!isFunction(handle)) {          //不是函数  2.1.1 onFulfilled 不是函数,其必须被忽略                this.thenPromise.value = resolveData;                this.thenPromise.status = 'resolve';                this.thenPromise._resolve();                return;            }            try { //如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e                returnVal = handle(resolveData);            } catch (error) {                this.thenPromise.status = 'reject';                this.thenPromise.value = error;                this.thenPromise._reject();            }            if (isObject(returnVal || isFunction(returnVal))) { //如果返回值为对象或者函数                if (returnVal == this.thenPromise) { //如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise                    this.thenPromise.status = 'reject';                    this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一对象');                } else if (returnVal instanceof Promise) { //如果 x 为 Promise ,则使 promise 接受 x 的状态                    try {                        then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));                    } catch (error) {                        this.thenPromise.status = 'reject';                        this.thenPromise.value = error;                        this.thenPromise._reject();                    }                } else {      //如果 x 为对象或者函数                    try {     //如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise                        var then = returnVal.then;                        if (isFunction(then)) {                            then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));                        }                    } catch (error) {                        this.thenPromise.status = 'reject';                        this.thenPromise.value = error;                        this.thenPromise._reject();                    }                }            } else {                this.thenPromise.value = returnVal;                this.thenPromise.status = 'resolve';                this.thenPromise._resolve();            }        }    }    Promise.resolve = function(value) {        return new Promise(function(re, rj) {            re(value)        })    }    Promise.reject = function(value) {        return new Promise(function(re, rj) {            re(value)        })    }    Promise.all = function(queue) {        if (Object.prototype.toString.call(queue) != "[object Array]") {            return;        }        var returnPromise = new Promise(function() {}),            resolveNum = 0;        for (var i = 0; i < queue.length; i++) {            queue[i].then(function() {                resolveNum++;                if (resolveNum == queue.length) {                    returnPromise._resolve();                }            });        }        return returnPromise;    }    Promise.race = function(queue) {        if (Object.prototype.toString.call(queue) != "[object Array]") {            return;        }        var returnPromise = new Promise(function() {}),            resolveNum = 0;        for (var i = 0; i < queue.length; i++) {            queue[i].then(function() {                returnPromise._resolve();            });        }        return returnPromise;    }    global.Promise = Promise;})(window);

转载地址:http://glsdx.baihongyu.com/

你可能感兴趣的文章
Tomcat性能调优
查看>>
Android自学--一篇文章基本掌握所有的常用View组件
查看>>
灰度图像和彩色图像
查看>>
FreeMarker-Built-ins for strings
查看>>
argparse - 命令行选项与参数解析(转)
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>
spring-boot支持websocket
查看>>
我理想中的前端工作流
查看>>
记一次Git异常操作:将多个repository合并到同一repository的同一分支
查看>>
Chrome 广告屏蔽功能不影响浏览器性能
查看>>
Android状态栏实现沉浸式模式
查看>>
使用Openfiler搭建ISCSI网络存储
查看>>
学生名单
查看>>
(转) 多模态机器翻译
查看>>
【官方文档】Nginx负载均衡学习笔记(三) TCP和UDP负载平衡官方参考文档
查看>>
矩阵常用归一化
查看>>
Oracle常用函数总结
查看>>
【聚能聊有奖话题】Boring隧道掘进机完成首段挖掘,离未来交通还有多远?
查看>>
考研太苦逼没坚持下来!看苑老师视频有点上头
查看>>
HCNA——RIP的路由汇总
查看>>