简单实现Promise(转)

http://imweb.io/topic/5bbc264b6477d81e668cc930

1. Promise的标准

Promise标准

可以看到promise的规范很详细很明确,只要将规范翻译成代码,就可以实现一个完整的Promise。当然本文只是对Promise的简单实现,一些复杂的情况暂且不考虑。

2. 简单实现Promise

2.1 构造函数

首先写出Promise的构造函数,Promise使用的是发布与订阅模式,调用promise上的then方法将resolve和reject回调分别加入onFulfilledCallback和onRejectedCallback回调函数集合,

然后调用resolve和reject方法触发回调函数集合中函数的执行。

function Promise(fn) {
  var self = this; self.status = 'pending'; // Promise初始状态为pending self.data = undefined; // Promise的值 self.onFulfilledCallback = []; // Promise resolve回调函数集合 self.onRejectedCallback = []; // Promise reject回调函数集合 fn(resolve, reject); // 执行传进来的函数,传入resolve, reject参数 } 

这里再考虑一下resolve函数和reject函数的实现,在构造函数中定义它们。

function Promise(fn) {
  var self = this; self.status = 'pending'; // Promise初始状态为pending self.data = undefined; // Promise的值 self.onFulfilledCallback = []; // Promise resolve回调函数集合 self.onRejectedCallback = []; // Promise reject回调函数集合 function resolve(value) { if (self.status === 'pending') { self.status = 'resolved'; self.data = value; for (var i = 0; i < self.onFulfilledCallback.length; i++) { self.onFulfilledCallback[i](value); } } } function reject(reason) { if (self.status === 'pending') { self.status = 'rejected'; self.data = reason; for (var i = 0; i < self.onRejectedCallback.length; i++) { self.onRejectedCallback[i](reason); } } } try { fn(resolve, reject); // 执行传进来的函数,传入resolve, reject参数 } catch (e) { reject(e); } } 

resolve和reject主要做的就是修改promise的状态,然后执行回调函数,逻辑比较简单。

2.2 then方法

Promise对象有一个then方法,用来注册Promise对象状态确定后的回调。这里需要将then方法定义在Promise的原型上。

Promise.prototype.then = function(onFulfilled, onRejected) {
  var self = this; // 根据标准,如果then的参数不是function,则我们需要忽略它 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(v) { return v}; onRejected = typeof onRejected === 'function' ? onRejected : function(r) { return r }; // Promise对象存在以下三种状态,对三种状态采用不同处理 if (self.status === 'resolved') { return new Promise(function(resolve, reject) { // todo }); } if (self.status === 'rejected') { return new Promise(function(resolve, reject) { // todo }); } if (self.status === 'pending') { return new Promise(function(resolve, reject) { // todo }); } } 

接下来,实现对三种情况的处理

Promise.prototype.then = function(onFulfilled, onRejected) {
  var self = this; // 根据标准,如果then的参数不是function,则我们需要忽略它 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(v) { return v}; onRejected = typeof onRejected === 'function' ? onRejected : function(r) { return r }; if (self.status === 'resolved') { // 这里promise的状态已经确定是resolved,所以调用onResolved return new Promise(function(resolve, reject) { try { // ret是onFulfilled的返回值 var ret = onFulfilled(self.data); if (ret instanceof Promise) { // 如果ret是一个promise,则取其值作为新的promise的结果 ret.then(resolve, reject); } else { // 否则,以它的返回值作为新的promise的结果 resolve(ret); } } catch (e) { // 如果出错,以捕获到的错误作为promise2的结果 reject(e); } }); } // 这里的逻辑跟前面一样,不再赘述 if (self.status === 'rejected') { return new Promise(function(resolve, reject) { try { var ret = onRejected(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { reject(ret); } } catch (e) { reject(e); } }); } if (self.status === 'pending') { // 如果当前的Promise还处于pending状态,则不能确定调用 // onResolved还是onRejecte,只能等到Promise状态确定后, // 才能确定如何处理 return new Promise(function(resolve, reject) { self.onFulfilledCallback.push(function(value) { try { var ret = onFulfilled(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { resolve(ret); } } catch (e) { reject(e); } }); self.onRejectedCallback.push(function(value) { try { var ret = onRejected(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { reject(ret); } } catch (e) { reject(e); } }); }); } } // 顺便实现一下catch方法 Promise.prototype.catch = function(onRejected) { return this.then(null, onRejected); } 

根据标准,onFulfilled和onRejected函数需要异步执行,所以我们需要稍微再修改一下代码。

function Promise(fn) {
  var self = this; self.status = 'pending'; // Promise初始状态为pending self.data = undefined; // Promise的值 self.onFulfilledCallback = []; // Promise resolve回调函数集合 self.onRejectedCallback = []; // Promise reject回调函数集合 function resolve(value) { if (self.status === 'pending') { self.status = 'resolved'; self.data = value; setTimeout(function() { for (var i = 0; i < self.onFulfilledCallback.length; i++) { self.onFulfilledCallback[i](value); } }); } } function reject(reason) { if (self.status === 'pending') { self.status = 'rejected'; self.data = reason; setTimeout(function() { for (var i = 0; i < self.onRejectedCallback.length; i++) { self.onRejectedCallback[i](reason); } }); } } try { fn(resolve, reject); // 执行传进来的函数,传入resolve, reject参数 } catch (e) { reject(e); } } Promise.prototype.then = function(onFulfilled, onRejected) { var self = this; // 根据标准,如果then的参数不是function,则我们需要忽略它 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(v) { return v}; onRejected = typeof onRejected === 'function' ? onRejected : function(r) { return r }; if (self.status === 'resolved') { // 这里promise的状态已经确定是resolved,所以调用onResolved return new Promise(function(resolve, reject) { setTimeout(function() { try { // ret是onFulfilled的返回值 var ret = onFulfilled(self.data); if (ret instanceof Promise) { // 如果ret是一个promise,则取其值作为新的promise的结果 ret.then(resolve, reject); } else { // 否则,以它的返回值作为新的promise的结果 resolve(ret); } } catch (e) { // 如果出错,以捕获到的错误作为promise2的结果 reject(e); } }); }); } // 这里的逻辑跟前面一样,不再赘述 if (self.status === 'rejected') { return new Promise(function(resolve, reject) { setTimeout(function() { try { var ret = onRejected(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { reject(ret); } } catch (e) { reject(e); } }); }); } if (self.status === 'pending') { // 如果当前的Promise还处于pending状态,则不能确定调用 // onResolved还是onRejecte,只能等到Promise状态确定后, // 才能确定如何处理 return new Promise(function(resolve, reject) { self.onFulfilledCallback.push(function(value) { setTimeout(function() { try { var ret = onFulfilled(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { resolve(ret); } } catch (e) { reject(e); } }); }); self.onRejectedCallback.push(function(reason) { setTimeout(function() { try { var ret = onRejected(self.data); if (ret instanceof Promise) { ret.then(resolve, reject); } else { reject(ret); } } catch (e) { reject(e); } }); }); }); } } // 顺便实现一下catch方法 Promise.prototype.catch = function(onRejected) { return this.then(null, onRejected); } 

至此,我们已经实现了Promise的基本功能了,让我们来测试一下吧!

const p = new Promise(function(resolve, reject) { setTimeout(function() { resolve(1); }, 2000); }); p.then(function(v) { console.log(v); return 2; }).then(function(v) { console.log(v); return new Promise(function(resolve, reject) { setTimeout(function() { resolve(3); }, 3000); }); }).then(function(v) { console.log(v); }); 

输出:

1
2
3

转载于:https://www.cnblogs.com/rubyxie/articles/9791353.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值