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

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

下面是几种调用

串行

 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   });

并行

 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)})

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

Task.resolve(‘data‘).then(function(data){
         console.log(data);
     })
时间: 2024-10-15 12:53:40

Promise A 规范的一个简单的浏览器端实现的相关文章

转:实现一个简单的服务端推送方案

原文来自于:http://blog.csdn.net/jiao_fuyou/article/details/17090355 客户端和服务端的交互有推和拉两种方式:如果是客户端拉的话,通常就是Polling:如果是服务端推的话,一般就是Comet,目前比较流行的Comet实现方式是Long Polling. 注:如果不清楚相关名词含义,可以参考:Browser 與 Server 持續同步的作法介紹. 先来看看Polling,它其实就是我们平常所说的轮询,大致如下所示: Polling 因为服务端

制作一个简单的浏览器WebView的使用

在Android中,要使用内置的浏览器,需要通过WebView组件来实现,核心是开源WebKit引擎. WebView是专门用来浏览网页的,既可以在XML文件中使用<WebView>标记添加,又可以在Java文件中通过new关键字创建,推荐使用XML方法. WebView最简单的应用就是在布局文件中定义一个WebView组件,在程序代码中实例化组件,并调用其loadUrl方法,传入需要访问的地址即可. 步骤: 布局文件中定义WebView 实例化WebView WebView webview=

SeaJS:一个适用于 Web 浏览器端的模块加载器

什么是SeaJS?SeaJS是一款适用于Web浏览器端的模块加载器,它同时又与Node兼容.在SeaJS的世界里,一个文件就是一个模块,所有模块都遵循CMD(Common Module Definition)规范.SeaJS本身遵循(Keep it Simple, Stupid)理念开发,API仅有几个. 为什么用SeaJS?假如我们要开发一个web应用App,在这个应用中需要使用jquery框架.App的首页index.html会用到module1.js,module1.js依赖module2

【Java】 实现一个简单文件浏览器(2)

接着上篇文章 接下来说下程序右侧的文件内容表格如何实现 FileTable类: FileTable基础于JTable类,构造函数里用setDefaultRenderer设置每行默认的渲染器为FileTableCellRenderer(下面会说如何实现) setAutoCreateRowSorter(true)函数自动创建一个默认的排序筛选器,等同于:setRowSorter(new TableRowSorter(model)) RowSorter:默认情况下,如果启用排序,那么排序时 JTabl

一个简单的 PC端与移动端的适配(通过UA)

只需在header引用个js文件, 原理就是判断UA里面的标识.  加下面代码添加到js文件,在头文件引用即可 var Pc_url = 'http://www.baidu.com'; //PC端网址var Phone_url = 'http://www.sougou.com'; //手机端网址function IsPC(){ var userAgentInfo = navigator.userAgent; var Agents = new Array("Android", "

Spring cloud实战 从零开始一个简单搜索网站(三)

上文已经完成了一个简单的   浏览器 到 Client 到CSDN端的通路 我们的架构是每个博客网址为一个单独的组件, 这里为了方便直接先用CSDN 那个组件复制下 我这里改成 SDN 修改下 application.properties   端口记得改 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/spring.application.name=sdnserver.port=8983 下面是TOMCAT   

一个简单有效的兼容IE7浏览器的办法

最近发现了一个简单有效的兼容IE7浏览器的办法 直接将下面代码复制道页面 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 但不是所有问题都能解决, 最关键的还是你的代码必须没太大的毛病,而且记着时刻清除浮动,保持良好的习惯.

Zeal:一个简单的离线 API 文档浏览器

Zeal 是一个简单的离线 API 文档浏览器,仿照 Dash(一个 OSX 应用) 写成,能在 Linux 和 Windows 上使用. 特点 在你的工作空间的任何地方中,使用 Alt + 空格(也可以自定义)快捷键去进行快速的文档搜索. 一次搜索多个文档集. 不需要网络连接. Zeal 是开源的!遵循 GPL 版权协议: 所有能用在 Dash 上的文档也可以用在 Zeal 中.这里可以看到一系列 Dash 支持的文档集 Zeal 的项目主页在:http://zealdocs.org/ zea

vue_cli下开发一个简单的模块权限系统之建立登录页面并且实现在浏览器输入地址出现内容

新建一个Login.vue(登录页面,先把Hello.vue的内容复制过来即可) 然后我们打开router下面的index.js,第一个箭头:(引入vue路由)第二个箭头(引入我们新建的Login.vue页面)第三个箭头(我们要使用这个路由)第四个箭头(配置路由,path表示在浏览器中输入的路由名称) 然后我们在浏览器中输入这个login页面的地址,就会出来内容了,这样一个简单的页面就建成了 因为我们要使用semantic-ui,所以我们安装一下semantic-ui,进入到命令行界面输入npm