JS神器 Promise 兼容
2017-08-19 00:00
246 查看
code:
与es6对比 [es6: Chrome 版本 60.0.3112.101(正式版本) (64 位)]
// 兼容 window.Promise (function(){ "use strict"; var Promise, proto; if(window.Promise) return; Promise = window.Promise = function(resolver){ var self=this, c; // check if(!(this instanceof Promise)) throw new Error('undefined is not a promise'); if(typeof resolver!=='function') throw new Error('Promise resolver '+resolver+' is not a function'); // init c = this.__Promise = { status:0, data:null, next:[], catched:false, done: function(data){ emit(self,data); }, fail: function(err){ emit(self,err,true); } }; if(resolver===noop) return this; // exec try{ resolver(c.done, c.fail); } catch(err){ c.fail(err); } return this; }; proto = Promise.prototype; function noop(){} function emit($pm, data, isFail) { var c=$pm.__Promise, n; if(c.status!==0) return; if(!isFail && (data instanceof Promise)) return data.then(c.done, c.fail); n = c.status = isFail ? 2 : 1; c.data = data; for(var i=0,l=c.next.length; i<l; i++){ exec(c.next[i][0], c.next[i] , c.data, isFail); } if(!isFail || c.catched) return; setTimeout(function(){ if(c.catched) return; throw '(in promise) '+data; }); } function exec($pm, fn, data, isFail){ if(typeof fn!=='function') emit($pm, data, isFail); try{ emit($pm, fn(data)); } catch(err){ emit($pm, err, true); } } Promise.all = function(arr){ var $pm=new Promise(noop), len=1, rt=[]; for(var i=0; i<arr.length; i++){ if(arr[i] instanceof Promise){ if(len<0) arr[i].__Promise.catched = true; else{ len++; (function(){ var n = i; arr .then( function(data){ rt = data; if(!--len) emit($pm,rt); }, function(err){ emit($pm,err,true); len = -1; } ); })(); } } else if(len>0) rt[i] = arr[i]; } if(!--len) $pm.__Promise.done(rt); return $pm; }; Promise.race = function(arr){ var $pm=new Promise(noop), isRt; for(var i=0; i<arr.length; i++){ if(arr[i] instanceof Promise){ if(isRt) arr[i].__Promise.catched = true; else{ arr[i].then( function(data){ isRt = true; emit($pm,data); }, function(err){ isRt = true; emit($pm,err,true); } ) } } else if(!isRt){ isRt = true; emit($pm, arr[i]); } } return $pm; }; Promise.resolve = function(data){ var $pm = new Promise(noop); emit($pm, data); return $pm; }; Promise.reject = function(err){ var $pm = new Promise(noop); emit($pm, err, true); return $pm; }; proto.then = function(done, fail){ var $pm=new Promise(noop), c=this.__Promise, s=c.status; c.catched = true; if(s===0) c.next.push([$pm, done, fail]); else if(s===1) exec($pm, done, c.data); else exec($pm, fail, c.data, true); return $pm; }; proto.catch = function(fail){ var $pm=new Promise(noop), c=this.__Promise, s=c.status; c.catched = true; if(s===0) c.next.push([$pm, null, fail]); else if(s===1) emit($pm, c.data); else exec($pm, fail, c.data, true); return $pm; }; })();
与es6对比 [es6: Chrome 版本 60.0.3112.101(正式版本) (64 位)]
code | consloe.log | Uncaught(es6) | Uncaught(兼容) |
---|---|---|---|
Promise(); | null | Uncaught TypeError: undefined is not a promise | Uncaught Error: undefined is not a promise |
Promise(1); | null | Uncaught TypeError: undefined is not a promise | Uncaught Error: undefined is not a promise |
new Promise(); | null | Uncaught TypeError: Promise resolver undefined is not a function | Uncaught Error: Promise resolver undefined is not a function |
new Promise(1); | null | Uncaught TypeError: Promise resolver 1 is not a function | Uncaught Error: Promise resolver 1 is not a function |
new Promise(function(done){ done(1); }).then(); | null | null | null |
new Promise(function(done){ done(1); }).then(2); | null | null | null |
new Promise(function(done){ done(1); }).catch(); | null | null | null |
new Promise(function(done){ done(1); }).catch(2); | null | null | null |
new Promise(function(done,fail){ fail({a:1}) }); | null | Uncaught (in promise) {a: 1} | Uncaught (in promise) [object Object] |
new Promise(function(done,fail){ fail(1); }).catch(); | null | Uncaught (in promise) 1 | Uncaught (in promise) 1 |
new Promise(function(done,fail){ fail(1); }).catch(2); | null | Uncaught (in promise) 1 | Uncaught (in promise) 1 |
new Promise(function(done){ done(1); }).then(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done,fail){ fail(1); }).catch(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done,fail){ done(1); fail(2); }).then(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done,fail){ fail(2); done(1); }).then(function(data){ console.log(data); }); | null | Uncaught (in promise) 2 | Uncaught (in promise) 2 |
new Promise(function(done){ setTimeout(function(){ done(1); }); }).then(function(data){ return data+1; }).then(function(data){ console.log(data); }); | 2 | null | null |
new Promise(function(done,fail){ fail(1); }).then(function(data){ console.log('then:', data); }).catch(function(data){ console.log('catch:', data); }); | catch: 1 | null | null |
new Promise(function(done,fail){ setTimeout(function() { fail(1); }); }).catch(function(data){ return 2; }).then(function(data){ console.log('then:', data); }); | then: 2 | null | null |
new Promise(function(){ throw 1; }).catch(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done,fail){ fail(2); throw 1; }).catch(function(data){ console.log(data); }); | 2 | null | null |
new Promise(function(done){ done(1); }).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | then: 1 | null | null |
new Promise(function(done,fail){ fail(1); }).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | catch: 1 | null | null |
new Promise(function(done){ done(Promise.resolve(1)); }).then(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done){ done(Promise.reject(1)); }).catch(function(data){ console.log(data); }); | 1 | null | null |
new Promise(function(done){ done(1); }).then(function(data){ return data+1; },function(data){ console.log('catch:', data); }).then(function(data){ console.log('then:', data); }); | then: 2 | null | null |
new Promise(function(done,fail){ fail(1); }).then(function(data){ console.log('then:', data); },function(data){ return data+1; }).then(function(data){ console.log('then2:', data); }); | then2: 2 | null | null |
new Promise(function(done,fail){ fail(1); }).then(function(data){ console.log('then:', data); },function(data){ return Promise.resolve(data+1); }).then(function(data){ console.log('then2:', data); }); | then2: 2 | null | null |
new Promise(function(done,fail){ fail(1); }).then(function(data){ console.log('then:', data); },function(data){ return Promise.reject(data+1); }).catch(function(data){ console.log('catch:', data); }); | catch: 2 | null | null |
var p1 = new Promise(function(done){ setTimeout(function(){ done(1); },2000); }); var p2 = new Promise(function(done){ setTimeout(function(){ done(2); }); }); Promise.all([0,p1,p2]).then(function(data){ console.log(data); }); | [0, 1, 2] | null | null |
var p1 = new Promise(function(done){ setTimeout(function(){ done(1); },2000); }); var p2 = new Promise(function(done,fail){ setTimeout(function(){ fail(2); }); }); Promise.all([p1,p2]).catch(function(data){ console.log(data); }); | 2 | null | null |
var p1 = new Promise(function(done){ setTimeout(function(){ done(1); },2000); }); var p2 = new Promise(function(done){ setTimeout(function(){ done(2); },1000); }); Promise.race([0,p1,p2]).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | then: 0 | null | null |
var p1 = new Promise(function(done){ setTimeout(function(){ done(1); },2000); }); var p2 = new Promise(function(done){ setTimeout(function(){ done(2); },1000); }); Promise.race([p1,p2]).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | then: 2 | null | null |
var p1 = new Promise(function(done){ setTimeout(function(){ done(1); },2000); }); var p2 = new Promise(function(done,fail){ setTimeout(function(){ fail(2); },1000); }); Promise.race([p1,p2]).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | catch: 2 | null | null |
var p1 = new Promise(function(done,fail){ setTimeout(function(){ fail(1); },2000); }); var p2 = new Promise(function(done){ setTimeout(function(){ done(2); },1000); }); Promise.race([p1,p2]).then(function(data){ console.log('then:', data); },function(data){ console.log('catch:', data); }); | then: 2 | null | null |
相关文章推荐
- JS实现复制功能,兼容各大主流浏览器复制神器 ZeroClipboard
- Promise - js异步控制神器
- js异步与解决Promise IE兼容问题
- 万能js实现翻页,动态生成内容自动翻页,兼容各种浏览器(已测试)----神器版!
- 纯js实现Div在页面垂直居中!可根据浏览器大小的改变而改变!兼容各种浏览器----神器版!
- 万能js实现翻页,动态生成内容自动翻页,兼容各种浏览器(已测试)----神器版!
- 文章标题js将网页表格导出为excel表格(兼容各种浏览器)
- 原生js--兼容获取窗口滚动条位置和窗口大小的方法
- html\css\js-dom在不同主流浏览器的兼容问题
- 兼容IE与firefox火狐的回车事件(js与jquery)
- js原声ajax包(兼容个浏览器)
- ireport超链接支持js事件简单实现 兼容火狐谷歌IE等浏览器
- 【原】js实现复制到剪贴板功能,兼容所有浏览器
- JS组件系列——表格组件神器:bootstrap table
- JS - Promise使用详解1(基本概念、使用优点)
- 关于js浏览器兼容问题
- 微信小程序 es6-promise.js封装请求 处理异步进程
- JS网页播放声音实现代码兼容各种浏览器
- JS读取并输出xml文件节点及属性(兼容IE,FF)
- MC Dialog js弹出层 完美兼容多浏览器(5.6更新)