var PENDING = 0
var FULFILLED = 1
var REJECTED = 2
function Promise(fn) {
var state = PENDING
var value = null
var handlers = []
function fulfill(result) {
state = FULFILLED
value = result
handlers.forEach(handle)
handlers = null
}
function reject(error) {
state = REJECTED
value = error
handlers.forEach(handle)
handlers = null
}
function resolve(result) {
try {
var then = getThen(result)
if(then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result)
} catch(e) {
reject(e)
}
}
function handle(handler) {
if(state === PENDING) {
// console.log('pending')
handlers.push(handler)
} else {
if(state === FULFILLED &&
typeof handler.onFulfilled === 'function') {
// console.log('fulfilled')
handler.onFulfilled(value)
}
if(state === REJECTED &&
typeof handler.onRejected === 'function') {
handler.onRejected(value)
}
}
}
this.done = function(onFulfilled, onRejected) {
setTimeout(function() {
handle({
onFulfilled: onFulfilled,
onRejected: onRejected
})
}, 0)
}
this.then = function(onFulfilled, onRejected) {
var self = this
return new Promise(function (resolve, reject) {
return self.done(function (result) {
if(typeof onFulfilled === 'function') {
try{
return resolve(onFulfilled(result))
} catch(ex) {
return reject(ex)
}
} else {
return resolve(result)
}
}, function(error) {
if(typeof onRejected === 'function') {
try {
return resolve(onRejected(error))
} catch(ex) {
return reject(ex)
}
} else {
return reject(error)
}
})
})
}
doResolve(fn, resolve, reject)
}
var p = function (){
return new Promise(function(resolve,reject){
setTimeout(function(){
reject('p 的结果');
}, 100);
});
}
var p2 = function (input){
return new Promise(function(resolve){
setTimeout(function(){
console.log('p2拿到前面传入的值:' + input)
resolve('p2的结果');
}, 100);
});
}
p()
.then(
function(res){console.log('p的结果:' + res); return 'p then方法第一次返回'},function(value){console.log(value);return 'p then方法第一次错误的返回'})
.then(function(res){console.log('p第一次then方法的返回:'+res);
return 'p then方法第二次返回'})
.then(p2)
.then(function(res){console.log('p2的结果:' + res)});
/*
Check if a value is a Promise and, if it is,
return the `then` method of that promise
@param {Promise|Any} value
@return {Function|Null}
*/
function getThen(value) {
var t = typeof value
if(value && (t === 'object' || t === 'function')) {
var then = value.then
if(typeof then === 'function') {
return then
}
}
return null
}
/*
Take a potentially misbehaving resolver function and make sure
onFulfilled and onRejected are only called once
Make no guarantees about asynchrony
@param {Function} fn A resolver function that may not be trusted
@param {Function} onFulfilled
@param {Function} onRejected
*/
function doResolve(fn, onFulfilled, onRejected) {
var done = false
try {
fn(function (value) {
if(done) return
done = true
onFulfilled(value)
}, function(reason) {
if(done) return
done = true
onRejected(reason)
})
} catch(err) {
if(done) return
done = true
onRejected(err)
}
}
console