标签:推荐 处理 实验 use throw es6 promise 异步 err
Promise API是ES6的推荐标准,该API是由各JavaScript的执行引擎在底层,通常是使用C++语言实现的
为了更好地理解Promise API的使用方法并探究其可能的实现方式,笔者在JavaScript层面对Promise API进行了实现。
该实现只是作为实验、学习使用,虽然与内置的实现功能相同,但是在设计和运行效率上肯定是不能相提并论。
我也希望之后能对自己的实现进行改善。
该实现在处理异步任务时,采用了轮询的方式来检测其状态的变化。
具体代码如下(注:笔者采用Node方式进行模块定义,需要时可以通过Browserify等工具处理成浏览器可用的版本):
"use strict";
const STATUS_PENDING = ‘pending‘,
STATUS_FULFILLED = ‘fulfilled‘,
STATUS_REJECTED = ‘rejected‘;
const POLL_INTERVAL = 200;
function JSPromise(executor){
if(!executor || typeof executor != ‘function‘){
throw "No executor specified for this promise!";
}
var _this = this;
this.promiseStatus = STATUS_PENDING;
this.resolved = false;
this.promiseValue = undefined;
this.rejectReason = undefined;
this.onFulfilled = undefined;
this.onRejected = undefined;
function resolve(value){
_this.promiseValue = value;
_this.promiseStatus = STATUS_FULFILLED;
}
function reject(reason){
_this.rejectReason = reason;
_this.promiseStatus = STATUS_REJECTED;
}
executor.apply(this, [resolve, reject]);
};
JSPromise.resolve = function(value){
return new JSPromise(function(resolve, reject){
resolve(value);
});
};
JSPromise.reject = function(reason){
return new JSPromise(function(resolve, reject){
reject(reason);
});
};
JSPromise.prototype.then = function(onFulfilled, onRejected){
if(this.resolved ||
(!onFulfilled && !onRejected) ||
(typeof onFulfilled != ‘function‘ && typeof onRejected != ‘function‘)){
return JSPromise.resolve(undefined);
}
const _this = this;
this.onFulfilled = (onFulfilled && typeof onFulfilled == ‘function‘)?onFulfilled: this.onFulfilled;
this.onRejected = (onRejected && typeof onRejected == ‘function‘)?onRejected: this.onRejected;
if(this.promiseStatus === STATUS_FULFILLED){
this.resolved = true;
if(!this.onFulfilled){
return JSPromise.resolve();
}
let retVal = this.onFulfilled.apply(this, [this.promiseValue]);
if(retVal instanceof JSPromise){
return retVal;
}else{
return JSPromise.resolve(retVal);
}
}
if(this.promiseStatus === STATUS_REJECTED){
this.resolved = true;
if(!this.onRejected){
return JSPromise.reject(this.rejectReason);
}
let retVal = this.onRejected.apply(this, [this.rejectReason]);
if(retVal instanceof JSPromise){
return retVal;
}else{
return JSPromise.resolve(retVal);
}
}
if(this.promiseStatus === STATUS_PENDING){
const _this = this;
return new JSPromise(function (resolve, reject){
setTimeout(function checkStatus(){
if(_this.resolved){
resolve();
}else if(_this.promiseStatus === STATUS_FULFILLED && _this.onFulfilled){
_this.resolved = true;
let retVal = _this.onFulfilled.apply(_this, [_this.promiseValue]);
if(retVal instanceof JSPromise){
retVal.then(function(value){
resolve(value);
});
}else{
resolve(retVal);
}
}else if(_this.promiseStatus === STATUS_REJECTED){
if(_this.onRejected){
_this.resolved = true;
let retVal = _this.onRejected.apply(_this, [_this.rejectReason]);
if(retVal instanceof JSPromise){
retVal.then(function(value){
resolve(value);
});
}else{
resolve(retVal);
}
}else{
reject(_this.rejectReason);
}
}else if(_this.promiseStatus === STATUS_PENDING){
setTimeout(function(){
checkStatus(resolve, reject);
}, POLL_INTERVAL);
}else{
_this.resolved = true;
resolve();
}
}, 0);
});
}
throw new Error("Unexpected status: "+_this.promiseStatus);
};
JSPromise.prototype.catch = function(onRejected){
if(this.resolved){
return JSPromise.resolve();
}
if(!onRejected || typeof onRejected != ‘function‘){
throw "Must specify an ‘onRejected‘ callback function as the argument!";
}
return this.then(undefined, onRejected);
};
module.exports = JSPromise;
欢迎批评指正,相互探讨。
本实验的源码和测试代码放置于github:https://github.com/waychan23/promise-js-impl。
标签:推荐 处理 实验 use throw es6 promise 异步 err
原文地址:http://www.cnblogs.com/waychan/p/6666600.html