两种方式手写实现Promise(基本版)
Promise / deferred 分开的版本
'use strict';
let myPromise = (deferred) => {
this._resolved = null;
this._rejected = null;
this.then = (resolve,reject) => {
switch (deferred.state){
case 'pending':
this._resolved = (typeof resolve === 'function') ?
resolve
: null;
this._rejected = (typeof reject === 'function') ?
reject
: null;
break;
case 'rejected':
(typeof reject === 'function')
&& reject.call(null,deferred.reason);
break;
case 'resolved':
(typeof resolve === 'function')
&& resolve.call(null,deferred.result);
break;
}
};
};
let myDeferred = () => {
let _self = this;
this.state = 'pending';
this.reason = null;
this.result = null;
this.promise = new myPromise(_self);
this.resolved = (val) => {
this.state = 'resolved';
this.result = val;
if(this.promise._resolved){
this.promise._resolved.call(null,val);
}
};
this.rejected = (err) => {
this.state = 'rejected';
this.reason = err;
if(this.promise._rejected){
this.promise._rejected.call(null,err);
}
};
};
USAGE
const fs = require('fs');
let getFileSync = function (path) {
let df = new myDeferred();
fs.readFile(path, (e, r) => {
if(e){
df.rejected(e);
}else{
df.resolved(r);
}
});
return df.promise;
};
let r =getFileSync('./README.md');
//pending
r.then(
//resolved
(val) => console.log(val),
//rejected
(err) => console.log(err)
);
一体化的版本
let myPromise = (fn) => {
let _self = this;
this.state = 'pending';
this.result = null;
this.reason = null;
this.resolvedHandler = null;
this.rejectedHandler = null;
this.resolved = (val) => {
_self.state = 'resolved';
_self.result = val;
if(typeof _self.resolvedHandler === 'function'){
_self.resolvedHandler(val);
}
};
this.rejected = (err) => {
_self.state = 'rejected';
_self.reason = err;
if(typeof _self.rejectedHandler === 'function'){
_self.rejectedHandler(err);
}
};
this._promise = {};
this._promise._p = _self;
this._promise.then = (resolvedHandler, rejectedHandler) => {
switch (_self.state){
case 'pending':
_self.resolvedHandler = (typeof resolvedHandler === 'function') ?
resolvedHandler
: null;
_self.rejectedHandler = (typeof rejectedHandler === 'function') ?
rejectedHandler
: null;
break;
case 'resolved':
(typeof resolvedHandler === 'function')
&& resolvedHandler(_self.result);
break;
case 'rejected':
(typeof rejectedHandler === 'function')
&& rejectedHandler(_self.reason);
}
};
fn(this.resolved,this.rejected);
return this._promise;
};
USAGE
const fs = require('fs');
let getFileSync = (path) => {
return new myPromise( (resolved, rejected) => {
fs.readFile(path, (e, r) => {
if(!e){
resolved(r);
}else{
rejected(e);
}
});
});
};
let r = getFileSync('./README.md');
//pending
r.then(
//resolved
(val) => console.log(val),
//rejected
(err) => console.log(err)
);