// 判断变量否为function
|
function isFunction(variable) {
|
return typeof variable === 'function';
|
}
|
|
// 定义promise状态常量
|
var PENDING = 'PENDING',
|
FULFILLED = 'FULFILLED',
|
REJECTED = 'REJECTED'
|
|
/**
|
*定义_Promise构造函数
|
*
|
* @param {*} handle 注册回调方法
|
*/
|
function _Promise(handle) {
|
if (!isFunction(handle)) {
|
throw Error("_Promise构造函数接收函数作为参数");
|
}
|
this._status = PENDING
|
this._value = undefined
|
this._fulfilledQueues = []
|
this._rejectedQueues = []
|
try {
|
handle(this._resolve.bind(this), this._reject.bind(this))
|
} catch (err) {
|
this._reject(err)
|
}
|
}
|
|
// 重写_Promise原型对象
|
_Promise.prototype = {
|
constructor: _Promise,
|
_resolve: function (val) {
|
var _this = this
|
function run() {
|
if (_this._status != PENDING) return;
|
_this._status = FULFILLED
|
function runFulfilled(value) {
|
var cb;
|
while (cb = _this._fulfilledQueues.shift()) {
|
cb(value)
|
}
|
}
|
function runRejected(error) {
|
var cb;
|
while (cb = _this._rejectedQueues.shift()) {
|
cb(error)
|
}
|
}
|
if (val instanceof _Promise) {
|
val.then(function (value) {
|
_this._value = value
|
runFulfilled(value)
|
}.bind(_this), function (err) {
|
_this._value = err
|
runRejected(err)
|
}.bind(_this))
|
} else {
|
_this._value = val
|
runFulfilled(val)
|
}
|
}
|
setTimeout(run, 0)
|
},
|
_reject: function (err) {
|
var _this = this
|
if (this._status !== PENDING) return
|
function run() {
|
_this._status = REJECTED
|
_this._value = err
|
var cb;
|
while (cb = _this._rejectedQueues.shift()) {
|
cb(err)
|
}
|
}
|
setTimeout(run, 0)
|
},
|
|
/**
|
*then方法
|
*
|
* @param {*} onFulfilled 异步成功的回调
|
* @param {*} onRejected 异步失败回调
|
* @returns 返回新的_Promise实例,支持链式调用
|
*/
|
then: function (onFulfilled, onRejected) {
|
var _value = this._value
|
var _status = this._status
|
var _this = this
|
return new _Promise(function (onFulfilledNext, onRejectedNext) {
|
function fulfilled(value) {
|
try {
|
if (!isFunction(onFulfilled)) {
|
onFulfilledNext(value)
|
} else {
|
var res = onFulfilled(value);
|
if (res instanceof _Promise) {
|
res.then(onFulfilledNext, onRejectedNext)
|
} else {
|
onFulfilledNext(res)
|
}
|
}
|
} catch (err) {
|
onRejectedNext(err)
|
}
|
}
|
var rejected = error => {
|
try {
|
if (!isFunction(onRejected)) {
|
onRejectedNext(error)
|
} else {
|
var res = onRejected(error);
|
if (res instanceof _Promise) {
|
res.then(onFulfilledNext, onRejectedNext)
|
} else {
|
onFulfilledNext(res)
|
}
|
}
|
} catch (err) {
|
onRejectedNext(err)
|
}
|
}
|
|
switch (_status) {
|
case PENDING:
|
_this._fulfilledQueues.push(fulfilled)
|
_this._rejectedQueues.push(rejected)
|
break
|
case FULFILLED:
|
fulfilled(_value)
|
break
|
case REJECTED:
|
rejected(_value)
|
break
|
}
|
})
|
},
|
|
/**
|
*catch方法
|
*
|
* @param {*} onRejected 失败时回调方法
|
* @returns 返回新的_Promise实例
|
*/
|
catch: function (onRejected) {
|
return this.then(undefined, onRejected)
|
}
|
}
|
|
// _Promise构造函数的部分静态方法
|
_Promise.resolve = function (value) {
|
if (value instanceof _Promise) return value
|
return new _Promise(function (resolve) {
|
return resolve(value)
|
})
|
}
|
_Promise.reject = function (value) {
|
return new _Promise(function (resolve, reject) {
|
return resolve(value)
|
})
|
}
|
|
/**
|
*并发多个异步事件
|
*
|
* @param {*} list 由_promise对象组成的数组集合
|
* @returns 返回新的_promise实例 支持链式调用
|
*/
|
_Promise.all = function (list) {
|
var _this = this
|
return new _Promise(function (resolve, reject) {
|
var values = []
|
var count = 0
|
list.forEach(function (e, i) {
|
_this.resolve(e).then(function (res) {
|
values[i] = res
|
count++
|
if (count === list.length) resolve(values);
|
}, function (err) {
|
reject(err)
|
})
|
})
|
})
|
}
|
|
/**
|
*不管成功或失败都执行的finally方法
|
*
|
* @param {*} cb 回调事件
|
* @returns 新的promise实例
|
*/
|
_Promise.finally = function (cb) {
|
return this.then(function (value) {
|
return _Promise.resolve(cb()).then(function () { return value; })
|
}, function (reason) {
|
return _Promise.resolve(cb()).then(function () { throw reason; })
|
})
|
}
|