异步Promise实现

异步回调的书写往往打乱了正常流的书写方式,在ECMAScript 6中实现了标准的Promise API,旨在

解决控制回调流程的问题。

简单的实现了Promise API:

  

  1     (function(w){
  2             function Promise(fn){
  3                 return this instanceof Promise ? this.init(fn) : new Promise(fn);
  4             }
  5             Promise.fulfill = function(m){return m;};
  6             Promise.reject = function(m){throw m;};
  7             Promise.map = {
  8                 resolve: "onFulfill",
  9                 reject: "onReject"
 10             }
 11             //异步自动生成promise并执行
 12             Promise.resolve = function(fn){
 13                 var p = new Promise();
 14                 setTimeout(function(){
 15                     p.resolve();
 16                 },0);
 17                 if(fn)
 18                     p.callback["onFulfill"] = fn;
 19                 return p;
 20             };
 21             Promise.all = function(){
 22                 var p = new Promise(),
 23                         args;
 24                 var counter = 0,ret = [];//收集结果,并传给p
 25                 var v,fn; //传入的函数,执行该函数,将结果保存至ret
 26                 if(arguments.length > 1){
 27                     args = [].slice.apply(arguments)
 28                 }else if({}.toString.call(arguments[0]) == "[object Array]"){
 29                     args = arguments[0];
 30                 }
 31                 for(var i=0,len=args.length;i<len;i++){
 32                     if(typeof args[i] == "function"){
 33                         args[i] = Promise.resolve(args[i]);
 34
 35                     }
 36
 37                     if(isPromise(args[i])) { //如果为promise对象,则将初始函数值传入数组
 38
 39                     }
 40                     (function(p,i){
 41                         p.then(function(v){
 42                             ret.push(v);
 43
 44                             if(--counter <= 0){
 45                                 ret.length = len;
 46                                 p.resolve(ret);
 47                             }
 48                         },function(e){
 49                             p.reject(e);
 50                         });
 51
 52                     })(args[i],i)
 53                     counter++;
 54                 }
 55                 return p;
 56             };
 57             Promise.prototype = {
 58                 init: function(fn){
 59                     var that = this;
 60                     this.state = ‘pending‘;
 61                     this.callback = {
 62                         onFulfill: Promise.fulfill,
 63                         onReject: Promise.reject
 64                     };
 65                     this.dirty = false;
 66                     this._next = null;
 67                     setTimeout(function(){
 68                         try{
 69                             fn && fn.call(that,that.resolve.bind(that),that.reject.bind(that));
 70                         }catch(e){
 71                             that.reject(e);
 72                         }
 73                     },0)
 74
 75                 },
 76                 then: function(onFulfill,onReject){
 77                     return post.call(this,onFulfill,onReject);
 78                 },
 79                 wait: function(mills){ //promise链在wait处被分裂成2段
 80                     var p = new Promise(),
 81                             start = new Date().getTime();
 82                     var id = setTimeout(function(){ //传入时间
 83                         p.resolve([this.val,new Date().getTime() - start])
 84                     },mills);
 85                     p.cancel = function(){
 86                         clearTimeout(id);
 87                     }
 88                     return p;
 89                 }
 90             }
 91             function post(onFulfill,onReject,onNotify,onComplete){
 92                 var p = new Promise(),
 93                         that = this;
 94                 if(arguments.length <= 2){
 95                     that._next = p;
 96                     that.callback["onFulfill"] = onFulfill;
 97                     that.callback["onReject"] = onReject;
 98                     this.dirty = true;
 99                 }
100                 return p;
101             }
102             function fire(promise,method,args){
103                 var next = "resolve",val;
104                 if(promise.state == "pending"){console.log(args)
105                     try{
106                         promise.val = val = promise.callback[Promise.map[method]].call(promise,args);
107                         promise.state = method;
108                     }catch(e){
109                         promise.val = val = e;
110                         next = "reject";
111                     }
112
113                     if(val && isPromise(val)){
114                         val._next = promise._next;
115                     }else{
116                         if(promise._next){
117                             fire(promise._next,next,val);
118                         }
119                     }
120
121                 }
122                 return promise;
123             }
124             function isPromise(o){
125                 return o && typeof o == "object" && o.then && typeof o.then == "function";
126             }
127             "reject,resolve".replace(/\w+/g,function(m){
128                 Promise.prototype[m] = function(args){
129                     return fire(this,m,args);
130                 }
131             })
132
133             w.Promise = Promise;
134         })(window)

简易的demo示范:

 1     var getJson = function(url){
 2             return new Promise(function(resolve,reject){
 3                 var xhr = new XMLHttpRequest();
 4                 if(!window.Promise)return;
 5                 xhr.open(‘get‘,url);
 6                 xhr.onreadystatechange = function(e){
 7                     if(xhr.readyState == 4){
 8                         if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
 9                             resolve(xhr.responseText);
10                         }else{
11                             reject(new Error(‘response error‘));
12                         }
13                     }
14                 };
15                 xhr.onerror = function(e){
16                     reject(new Error(‘ajax error‘));
17                 }
18                 xhr.send();
19             });
20         };
21
22         var body = document.body;
23         var addHtml = function(html){
24             if(typeof  html != ‘string‘) return;
25             var p = document.createElement(‘p‘);
26             p.textContent = html;
27             body.insertBefore(p,loading);
28         };
29         var addHead = function(html){
30             if(typeof html !== ‘string‘) return;
31             var h = document.createElement(‘h2‘);
32             h.textContent = html;
33             body.insertBefore(h,loading);
34         }
35         var log = function(msg){console.log(msg)};
36         var loading = document.getElementById(‘loading‘);
37
38 /*        getJson(‘../json/head.json‘).then(JSON.parse).then(function(html){
39             addHead(html.content);
40             Promise.all(html.urls.map(getJson)).then(function(arr){
41                 arr.forEach(function(content){
42                     addHtml(JSON.parse(content).content);
43                 })
44             }).catch(function(e){
45                 log(‘error in loading content: ‘+ e);
46             })
47         }).catch(function(e){
48             log(‘error: ‘ + e);
49         }).then(function(){
50             loading.style.display = ‘none‘;
51         })*/
52
53         getJson(‘../json/head.json‘).then(JSON.parse).then(function(html){
54             addHead(html.content);
55             var promise = Promise.resolve();
56             html.urls.forEach(function(url,i){
57                 promise = promise.then(function(){
58                     return getJson(url);
59                 }).then(JSON.parse).then(function(html){
60                     addHtml(html.content);
61                 }).catch(function(e){
62                     log(‘error in loading body: ‘+ e );
63                 }).then(function(){
64                     if(i == html.urls.length-1)
65                         loading.style.display = ‘none‘;
66                 })
67             })
68         })
时间: 2024-10-13 22:01:35

异步Promise实现的相关文章

异步Promise

(function(w){ function Promise(fn){ return this instanceof Promise ? this.init(fn) : new Promise(fn); } Promise.fulfill = function(m){return m;}; Promise.reject = function(m){throw m;}; Promise.map = { resolve: "onFulfill", reject: "onRejec

异步-promise、async、await

下面代码打印结果是? setTimeout(()=>{ console.log(1) }) new Promise((resolve,reject)=>{ console.log(2) resolve() }) .then(()=>{ console.log(3) }) new Promise((resolve,reject)=>{ console.log(4) resolve() }) .then(()=>{ console.log(5) }) setTimeout(()=

promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的通知机制. 异步:当事情处理完成后被请求者会发信息通知请求者该事情处理完成.在这期间被请求者可以选择是继续等待命令请求完成还是去做其他事等待被请求者返回. 同步:当事情处理完成后被请求者不会告知请求者,等到请求者发来询问是才会告知 阻塞:非阻塞 指的是请求者 阻塞:针对请求者来说的,委托其他人处理一

javascript基础修炼(7)——Promise,异步,可靠性

开发者的javascript造诣取决于对[动态]和[异步]这两个词的理解水平. 一. 别人是开发者,你也是 Promise技术是[javascript异步编程]这个话题中非常重要的,它一度让我感到熟悉又陌生,我熟悉其所有的API并能够在编程中相对熟练地运用,却对其中原理和软件设计思想感到陌生,即便我读了很多源码分析和教程也一度很难理解为什么Promise这样一个普通的类能够实现异步,也曾尝试着去按照Promise/A+规范来编写Promise,但很快便陷入了一种更大的混乱之中.直到我接触到一些软

异步编程解决方案

事件发布/订阅模式 promise/deferrd模式 流程控制模式 事件发布/订阅模式 事件监听器模式是异步回调的事件化,又称发布订阅/模式 node核心模块events 方法 addListener/on once removeListener removeAllListeners emit 简单操作 let events = require('events') let request = require('http').request let emit = new events.Event

promise介绍

promise简介 Promise的出现,原本是为了解决回调地狱的问题.所有人在讲解Promise时,都会以一个ajax请求为例,此处我们也用一个简单的ajax的例子来带大家看一下Promise是如何使用的. ajax请求的传统写法: getData(method, url, successFun, failFun){ var xmlHttp = new XMLHttpRequest(); xmlHttp.open(method, url); xmlHttp.send(); xmlHttp.on

Angular:Promise.all()的具体应用

现有项目开发中,从后台获取数据用异步promise,可是异步的数据要顺序获取真的是好费劲啊,还好解锁了promise.all(),下面来看代码吧! 遍历this.groupList通过groupID获取组内成员,将获取的成员push到finalAccount数组,this.groupList遍历完成以后,需要将finalAccount发送到父组件内,可是异步的话怎么发都有问题惹,改成promise.all()问题就解决了. const array = []; this.groupList.for

手写一个promise

Promise A+ 规范:https://promisesaplus.com/ 代码实现 class myPromise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedArray = []; this.onRejectedArray = []; const resolve = (val) => { if (this

对Promise的一些深入了解

1.介绍promise和模仿Promise.all和Promise.race promise的设计主要是解决回调地狱(接收结果用回调函数来处理,但必须传入回调函数)的问题,由一层层嵌套回调函数改为由then来执行. 例如: // callback用于接收返回结果, 异步方式 fs.readFile("filePath", callback); // 还有一种方式 cosnt { promises: fs } = require("fs"); // 用promise包