码迷,mamicode.com
首页 > 其他好文 > 详细

Promise A 规范的一个简单的浏览器端实现

时间:2016-09-09 20:54:09      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

简单的实现了一个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)
View Code

下面是几种调用

串行

技术分享
 1 var task = new Task(function(resolve, reject) {
 2     setTimeout(function() {
 3       resolve(‘aaaa‘);
 4     }, 100);
 5   })
 6   var task1 = function() {
 7     return new Task(function(resolve, reject) {
 8       setTimeout(function() {
 9         resolve(‘bbbb‘);
10       }, 100);
11     })
12   }
13   var task2 = function() {
14     return new Task(function(resolve, reject) {
15       setTimeout(function() {
16         resolve(‘cccc‘);
17       }, 100);
18     })
19   }
20   var task3 = function() {
21     return new Task(function(resolve, reject) {
22       setTimeout(function() {
23         reject(‘dddd‘);
24       }, 100);
25     })
26   }
27   task.then(task1).then(task2).then(task3).then(function(data) {
28     console.log(data)
29   }, function(error) {
30       console.log(data)
31   });
View Code

并行

技术分享
 1  var task = new Task(function(resolve, reject) {
 2     setTimeout(function() {
 3       resolve(‘aaaa‘);
 4     }, 100);
 5   })
 6   var task2 = new Task(function(resolve, reject) {
 7     setTimeout(function() {
 8       resolve(‘aaaa‘);
 9     }, 100);
10   })
11   var task3 = new Task(function(resolve, reject) {
12     setTimeout(function() {
13       resolve(‘aaaa‘);
14     }, 100);
15   })
16   var task4 = new Task(function(resolve, reject) {
17     setTimeout(function() {
18       resolve(‘aaaa‘);
19     }, 100);
20   })
21   var task5 = new Task(function(resolve, reject) {
22     setTimeout(function() {
23       resolve(‘aaaa‘);
24     }, 100);
25   })
26  //并行
27  Task.all([task,task2,task3,task4,task5]).then(function(data){ console.log(data)})
View Code

创建一个一开始就是 释放状态的 task

Task.resolve(‘data‘).then(function(data){
         console.log(data);
     })

 

Promise A 规范的一个简单的浏览器端实现

标签:

原文地址:http://www.cnblogs.com/btgyoyo/p/5857919.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!