简单的实现了一个promise 的规范,留着接下来模块使用。感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码
主要是Then 函数。回调有点绕人。
1 !(function(win) { 2 3 4 5 function Task(resolver) { 6 if (!resolver || (typeof resolver).toUpperCase() != 'FUNCTION') { 7 throw 'task arg is function,and is must'; 8 return; 9 } 10 11 12 if (!(this instanceof Task)) return new Task(resolver); 13 14 var self = this; 15 //PENDING,FULFILLED,REJECTED 16 self.statu = 'PENDING'; 17 self.callbackok = null; 18 self.callbackreject = null; 19 20 self.value = null; 21 self.reason = null; 22 23 function resolve(data) { 24 self.statu = 'FULFILLED'; 25 self.value = data || {}; 26 self.callbackok && self.callbackok(self.value); 27 } 28 29 function reject(reason) { 30 self.statu = 'REJECTED'; 31 self.reason = reason || {}; 32 self.callbackreject && self.callbackreject(self.reason); 33 } 34 35 36 resolver(resolve, reject); 37 38 } 39 40 41 Task.all = function(arr) { 42 43 if (!(arr instanceof Array)) { 44 throw 'arr must be Task Array'; 45 return; 46 } 47 48 return Task(function(resolve, reject) { 49 var dataarr = {}; 50 var len = arr.length; 51 for (var i = 0; i < len; i++) { 52 (function(c) { 53 console.log(arr[c]); 54 arr[c].then(function(data) { 55 dataarr[c] = data; 56 len--; 57 if (len == 0) { 58 var data = new Array(len); 59 for (var item in dataarr) { 60 data[item] = dataarr[item]; 61 } 62 resolve(data); 63 } 64 65 }, function(error) { 66 reject(error); 67 }) 68 })(i) 69 } 70 }) 71 } 72 73 //创建一个成功状态的Task对象 74 Task.resolve = function(value) { 75 76 return new Task(function(resolve) { 77 resolve(value); 78 }) 79 } 80 81 Task.prototype.then = function(onFulfilled, onRejected) { 82 83 var task = this; 84 85 return Task(function(resolve, reject) { 86 87 function callback(value) { 88 89 var ret = (typeof onFulfilled).toUpperCase() == 'FUNCTION' && onFulfilled(value) || value; 90 91 if (isThenable(ret)) { 92 ret.then(function(value) { 93 resolve(value); 94 }, function(reason) { 95 reject(reason); 96 }); 97 } else { 98 resolve(ret); 99 } 100 } 101 102 function errorback(reason) { 103 reason = (typeof onRejected).toUpperCase() == 'FUNCTION' && onRejected(reason) || reason; 104 reject(reason); 105 } 106 107 if (task.statu === 'PENDING') { 108 task.callbackok = callback; 109 task.callbackreject = errorback; 110 } else if (task.statu === 'FULFILLED') { 111 callback(task.value); 112 } else if (task.statu === 'REJECTED') { 113 errorback(task.reason); 114 } 115 116 }); 117 118 } 119 120 var isThenable = function(obj) { 121 return obj && typeof obj['then'] == 'function'; 122 } 123 124 window.Task = Task; 125 126 })(window)