promise 源码 简单分析
//全局宏定义
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
//Promise构造函数
function Promise(fn) {
var self = this;
self.state = PENDING;//初始化状态
self.value = null;//存储异步结果的对象变量
self.handlers = [];//存储回调函数,这里没保存失败回调函数,因为这是一个dome
//异步任务成功后处理,这不是回调函数
function fulfill(result) {
if (self.state === PENDING) {
self.state = FULFILLED;
self.value = result;
for (var i = 0; i < self.handlers.length; i++) {
self.handlers[i](result);
}
}
}
//异步任务失败后的处理,
function reject(err) {
if (self.state === PENDING) {
self.state = REJECTED;
self.value = err;
}
}
fn && fn(fulfill, reject);
}
//使用then方法添加回调函数,把这次回调函数return的结果当做return的promise的resolve的参数
Promise.prototype.then = function (onResolved, onRejected) {
var self = this;
return new Promise(function (resolve, reject) {
var onResolvedFade = function (val) {
var ret = onResolved ? onResolved(val) : val;//这一步主要是then方法中传入的成功回调函数通过return来进行链式传递结果参数
if (Promise.isPromise(ret)) {//回调函数返回值也是promise的时候
ret.then(function (val) {
resolve(val);
});
}
else {
resolve(ret);
}
};
var onRejectedFade = function (val) {
var ret = onRejected ? onRejected(val) : val;
reject(ret);
};
self.handlers.push(onResolvedFade);
if (self._status === FULFILLED) {
onResolvedFade(self._value);
}
if (self._status === REJECTED) {
onRejectedFade(self._value);
}
});
}
Promise.isPromise = function (val) {
return val && typeof val.then === 'function'
}
function async(value) {
var pms = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(value);
}, 1000);
// resolve(value);
});
return pms;
}
debugger
// async(1).then(function (result) {
// console.log('the result is ', result);//the result is 2
// return result;
// }, function(){}).then(function (result) {
// console.log(++result);//2
// });
var p1 = async(1);
var p2 = p1.then(function (result) {
console.log('the result is ', result);//the result is 2
return result;
}, function(){})
var p3 = p2.then(function (result) {
console.log(++result);//2
});
丑陋的流程图..
-
黑色代表正常调用流程
-
虚线代表等待,异步
-
紫色代表一秒后触发
总结
- 实现的关键在于每个then会new一个新的promise 并返回,
- 由于只是最简单的实现 此处并未考虑很多全面的情况,比如async 执行的必须是异步函数(如 本文中settimeout),不可以是同步,
- 因为 正式由于异步操作 才会先去执行后面的then函数,从而在第一个promise对象的handlers里加入then内部的回调函数,
- 如果第一个函数是同步的则会导致第一个promise对象的handlers为空,
- 关于上面提到的问题也好解决 其实就是为fullfiled函数内部用settimeout包裹,这样就会先执行后面的then方法,而不是先reslove()由于这不是重点 读者可以去实现
- 而 正规的promsie 如果用户传入的是同步函数的话会立即把promsie对象的内部状态改为fulllfiled状态,