1. Promise1.0 版本
简单的发布订阅实现 Promise
存在的问题是:then 方法执行回调函数的时候 value 值不确定
function Promise(fn) {
// 同步任务执行得到的结果value,作为私有变量存储在Promise中
var value = undefined;
// 模拟then方法
this.then = function(callback) {
callback(value);
}
// 模拟resolve
function resolve(val) {
value = val;
}
// 执行异步任务
fn(resolve);
}
2. Promise 2.0 版本
通过加入状态标志位,来百分之百确保回调执行的时候,value 值一定存在
相比第一版,添加了两个私有变量,status 和 cb。
function Promise(fn) {
// 异步任务执行得到的结果即 value,作为私有变量存储在Promise中
var value = undefined;
// 异步任务当前的状态(pending | resolved),作为私有变量存储在Promise
var status = "pending";
// 异步任务暂存
var cb = null;
// 模拟then方法
this.then = function(callback) {
// 1.如果fn执行结束(意味着一个同步任务),直接执行回调即可
if(status == "resolved") {
callback(value);
}
// 2.如果fn执行还未结束(意味着一个异步任务),暂存callback回调以后执行
if(status == "pending") {
cb = callback;
}
}
// 模拟resolve方法
function resolve(val) {
pending = "resolved";
value = val;
// 1.如果回调函数暂存了,执行回调
if(cb) {
cb(value);
}
// 2.如果回调函数未暂存,啥也不用做
}
fn(resolve);
}
3. Promise 3.0 版本
then 方法,需要返回一个 Promise,这样能链式调用
相比第二版,添加了一个私有变量 nResolve
function Promise(fn) {
var value = undefined;
var status = "pending";
var cb = null;
var nResolve = null;
this.then = function(callback) {
return new Promise(function(nextResolve) {
// 1.如果fn执行结束(意味着一个同步任务),直接执行回调即可
if(status == "resolved") {
let nextValue = callback(value);
nextResolve(nextValue);
}
// 2.如果fn执行未结束(意味着一个异步任务),暂存callback回调以后执行,暂存nextResolve以后执行
if(status == "pending") {
cb = callback;
nResolve = nextResolve;
}
})
}
function resolve(val) {
status = "resolved";
value = val;
// 1.如果回调函数存在了,执行回调和nextReoslve
if(cb) {
let nextValue = cb(value);
nResolve(nextValue);
}
// 2.如果回调函数不存在,啥也不用做
}
fn(resolve);
}
4. Promise 4.0 版本
如果then方法返回的就是一个Promise对象,那么我们得处理一下,获取里面的value
function Promise(fn) {
var value = undefined;
var status = "pending";
var cb = null;
var nResolve = null;
this.then = function(callback) {
return new Promise(function(resolve) {
// 1.如果fn执行结束(意味着一个同步任务),直接执行回调即可
if(status == "resolved") {
let nextValue = callback(value);
nextResolve(nextValue);
}
// 2.如果fn执行未结束(意味着一个异步任务),暂存callback回调以后执行,暂存nextResolve以后执行
if(status == "pending") {
cb = callback;
nResolve = nextResolve;
}
});
}
function resolve(val) {
// 判断下,这个val是否是个Promise
if(val && typeof val.then == "function") {
val.then(resolve);
}
status = "resolved";
value = val;
// 1.如果回调函数存在了,执行回调和nextReoslve
if(cb) {
let nextValue = cb(value);
nResolve(nextValue);
}
// 2.如果回调函数不存在,啥也不用做
}
fn(resolve);
}
5. Promise 5.0 版本
很简单,只要把 reject 加入即可,思路和 resolve 类似
function Promise(fn) {
var value = undefined;
var status = "pending";
var cb = null;
var nResolve = null;
var nReject = null;
this.then = function(callback) {
return new Promise(nextResolve, nextReject) {
// 1.如果fn执行结束(意味着一个同步任务),直接执行回调即可
if(status == "resolved") {
let nextValue = callback(value);
nextResolve(nextValue);
}
if(status == "rejected") {
let nextError = callback(value);
nextReject(nextError);
}
// 2.如果fn执行未结束(意味着一个异步任务),暂存callback回调以后执行,暂存nextResolve以后执行
if(status == "pending") {
cb = callback;
nResolve = nextResolve;
}
}
}
function resolve(val) {
// 判断下,这个val是否是个Promise
if(val && typeof val.then == "function") {
val.then(resolve);
}
status = "resolved";
value = val;
// 1.如果回调函数存在了,执行回调和nextReoslve
if(cb) {
let nextValue = cb(value);
nResolve(nextValue);
}
// 2.如果回调函数不存在,啥也不用做
}
function reject(val) {
// 判断下,这个val是不是Promise
if(val && typeof val.then == "function") {
val.then(reject);
}
status = "rejected";
value = val;
// 1.如果回调函数存在,执行回调和nextReject
if(cb) {
let nextError = cb(value);
nReject(nextError);
}
// 2.如果回调函数不存在,啥也不用做
}
fn(resolve, reject);
}
6. 添加try catch
存在的问题:resolve, then 方法里面的异常无法捕获,需要 try catch 交给 下个promise 来处理
所以 then().catch() 这种写法,可以保证捕获内部的错误
function Promise(fn) {
var value = undefined;
var status = "pending";
var cb = null;
var nResolve = null;
var nReject = null;
this.then = function(callback) {
return new Promise(nextResolve, nextReject) {
let nextValue = undefined,
nextError = undefined;
// 1.如果fn执行结束(意味着一个同步任务),直接执行回调即可
if(status == "resolved") {
try {
nextValue = callback(value);
}
catch(e) {
nextReject(e);
}
nextResolve(nextValue);
}
if(status == "rejected") {
try {
nextError = callback(value);
}
catch(e) {
nextReject(e);
}
nextReject(nextError);
}
// 2.如果fn执行未结束(意味着一个异步任务),暂存callback回调以后执行,暂存nextResolve以后执行
if(status == "pending") {
cb = callback;
nResolve = nextResolve;
}
}
}
function resolve(val) {
// 判断下,这个val是否是个Promise
if(val && typeof val.then == "function") {
val.then(resolve);
}
status = "resolved";
value = val;
// 1.如果回调函数存在了,执行回调和nextReoslve
let nextValue = undefined;
if(cb) {
try {
nextValue = cb(value);
}
catch(e) {
nReject(e);
}
nResolve(nextValue);
}
// 2.如果回调函数不存在,啥也不用做
}
function reject(val) {
// 判断下,这个val是不是Promise
if(val && typeof val.then == "function") {
val.then(reject);
}
status = "rejected";
value = val;
// 1.如果回调函数存在,执行回调和nextReject
if(cb) {
let nextError = cb(value);
nReject(nextError);
}
// 2.如果回调函数不存在,啥也不用做
}
fn(resolve, reject);
}