自制简单的promise
现在es6的promise已经是用的很广泛的,可以有效的解决地域回调的问题。
那么现在我们可以制作一个简单的promise,让自己更加熟悉promise。
一.回顾promise
先我们需要了解一下promise的用法。以下demo
var p=new Promise(function(resolve,reject){ setTimeout(function(){ resolve("success") },1000); console.log("创建一个新的promise"); }) p.then(function(x){ console.log(x) }) //输出: 创建一个新的promise success
以上就是一个promise的实例。从上述例子可以看出,promise可以处理异步操作。此外还可以链式调用
二.了解一下promise规范https://promisesaplus.com/
我们主要关心它的要求有一下几点:
1.一个promise必须有3个状态,pending,fulfilled(resolved),rejected当处于pending状态的时候,可以转移到fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,就不可变。 2.一个promise必须有一个then方法,then方法接受两个参数: 3.为了实现链式调用,then方法必须返回一个promise
三.制作promise
接下来我们来制作简单的promise,以下将分几个版本,来循序渐进的增加内容
1) v1.0版本
function myPromise(constructor){ let self=this; self.status="pending" //定义状态改变前的初始状态 self.value=undefined;//定义状态为resolved的时候的状态 self.reason=undefined;//定义状态为rejected的时候的状态 function resolve(value){ //两个==="pending",保证了状态的改变是不可逆的 if(self.status==="pending"){ self.value=value; self.status="resolved"; } } function reject(reason){ //两个==="pending",保证了状态的改变是不可逆的 if(self.status==="pending"){ self.reason=reason; self.status="rejected"; } } //捕获构造异常 try{ constructor(resolve,reject); }catch(e){ reject(e); } }
同时在原型链上增加then方法
myPromise.prototype.then=function(onFullfilled,onRejected){ let self=this; switch(self.status){ case "resolved": onFullfilled(self.value); break; case "rejected": onRejected(self.reason); break; default: } }
然后测试一下
var p=new myPromise(function(resolve,reject){resolve(1)}); p.then(function(x){console.log(x)}) //输出1
但是我们可以发现这边是没有异步过程的,即then里面是没有处理内容的
v1.1
增加异步功能
function myPromise(constructor){ let self=this; self.status="pending" //定义状态改变前的初始状态 self.value=undefined;//定义状态为resolved的时候的状态 self.reason=undefined;//定义状态为rejected的时候的状态 self.onFullfilledArray=[]; self.onRejectedArray=[]; function resolve(value){ if(self.status==="pending"){ self.value=value; self.status="resolved"; self.onFullfilledArray.forEach(function(f){ f(self.value); //如果状态从pending变为resolved, //那么就遍历执行里面的异步方法 }); } } function reject(reason){ if(self.status==="pending"){ self.reason=reason; self.status="rejected"; self.onRejectedArray.forEach(function(f){ f(self.reason); //如果状态从pending变为rejected, //那么就遍历执行里面的异步方法 }) } } //捕获构造异常 try{ constructor(resolve,reject); }catch(e){ reject(e); } }
myPromise.prototype.then=function(onFullfilled,onRejected){ let self=this; switch(self.status){ case "pending": self.onFullfilledArray.push(function(){ onFullfilled(self.value) }); self.onRejectedArray.push(function(){ onRejected(self.reason) }); break; case "resolved": onFullfilled(self.value); break; case "rejected": onRejected(self.reason); break; default: } }
现在在来测试已经可以发出then了
但是现在还无法处理链式调用then
v1.3
增加then链式调用
v1.3.1
最简单的就是then返回一个对象,可以进行链式调用
myPromise.prototype.then=function(onFullfilled,onRejected){ let self=this; switch(self.status){ case "pending": self.onFullfilledArray.push(function(){ onFullfilled(self.value) }); self.onRejectedArray.push(function(){ onRejected(self.reason) }); break; case "resolved": onFullfilled(self.value); break; case "rejected": onRejected(self.reason); break; default: } return this }
一个简单的this就是promise对象本身,这样就可以了,按时this永远都是同一个promise对象,即then里的value永远都是相同的
因此我们需要返回一个新的promise
v1.3.2
promise.prototype.then = function(onFullfilled, onRejected) { var self = this let promise2 switch (self.status) { case "pending": promise2 = new promise(function(resolve, reject) { self.onFullfilledArray.push(function() { try { let temple = onFullfilled(self.value) resolve(temple) } catch (e) { reject(e) } }) self.onRejectedArray.push(function() { try { let temple = onRejected(self.reason); resolve(temple) } catch (e) { reject(e) // error catch } }) }) break; case "resolved": promise2 = new promise(function(resolve, reject) { try { let temple = onFullfilled(self.value); //将上次一then里面的方法传递进下一个Promise的状态 resolve(temple); } catch (e) { reject(e); //error catch } }) break; case "rejected": promise2 = new promise(function(resolve, reject) { try { let temple = onRejected(self.reason); //将then里面的方法传递到下一个Promise的状态里 resolve(temple); } catch (e) { reject(e); } }) break; default: } return promise2; }
至此简单的promise已经完成了。但是这个promise还是有不少问题的,如then里面直接使用primise等。这些都是优化问题。
我们这样就知道了promise的运行机制了。
觉得不错的请点赞,谢谢。
相关推荐
nmgxzm00 2020-11-10
xixixi 2020-11-11
88254251 2020-11-01
MarukoMa 2020-09-02
88234852 2020-09-15
陈旭阳 2020-08-31
whynotgonow 2020-08-19
前端开发Kingcean 2020-07-30
whynotgonow 2020-07-29
bowean 2020-07-08
前端开发Kingcean 2020-07-08
88520191 2020-07-05
前端开发Kingcean 2020-06-27
88481456 2020-06-18
whynotgonow 2020-06-16
88520191 2020-06-13
88520191 2020-06-13
89500297 2020-06-13