//Promise实现原理 // 实例方法 // then // catch // new P( 函数 ).then(functon(){}).then(function(){}) // let p = new MyPromise(); // p.resolve(); //不允许的 // 静态方法 // all // race // 属性 // status : pending / resolved / rejected // resolve / reject // 要求, 每个promise对象, status状态初始为pending // 该属性不可直接修改,只能通过回调 修改 // 并且,状态一旦被修改, 不可逆. // 执行目标函数时, 需要传参数, resolve, reject function MyPromise(main){ let status = "pending"; //MyPromise刚被创建的初始化状态 let listTask = []; //定义一个数组,用于存储.then()里函数 let exceptionHander = null; //用于捕捉错误 function resolve(msg){ //如果函数返回resolve()方法则调用 if(status == "pending"){ //如果状态为pending则执行,否则不执行,程序结束 status = "resolve"; //函数顺利执行完将promise状态改为resolve let next = listTask.shift(); //拿出数组中第一个 let newp = next(msg); if(newp instanceof MyPromise){ //如果拿出来函数也new MyPromise,则执行 listTask.forEach(t=>{ newp.then(t); //例 new MyPromise(ajaxB).then(function(){ return new MyPromise(ajaxC)}).then(ajaxD).catch(function(e){console.log(e)}) }) } } } function rejected(msg){ //如果返回rejected,执行此函数 if(status == "pending"){//如果当前MyPromise状态为pending status = "rejected"; //更改状态为rejected ,抛出异常,输出方法里的msg if(exceptionHander){ //有catch则调用,否则报错 }else{ exceptionHander(msg); } } } this.then = function(task){ //讲第一个new Promise后面所有.then加入listTask数组里 console.log(this); listTask.push(task); return this; //返回,循环加入 }, this.catch = function(fn){ exceptionHander = fn; } this.getStatus = function(){ return status; } main(resolve,rejected.bind(this));//给第一个函数两个参,函数也需要设置两个参数接收,否则报错 } MyPromise.all = function(args){ let count = 0; let task = null; function isOver(){ count++; if(count == args.length) task(); } args.forEach(p=>{ p.then(isOver); }) return then(fn){ task = fn; } }
测试以上
<script src="Promise.js"></script> <!-- <script src="原生JS实现Promise.js"></script> --> <script> function ajaxA(resolve,reject){ console.log("ajaxA start!"); setTimeout(()=>{ console.log("ajaxA end!"); resolve(); },Math.random()*2000) } function ajaxB(resolve,reject){ console.log("ajaxB start!"); setTimeout(()=>{ console.log("ajaxB end!"); resolve(); },Math.random()*2000) } function ajaxC(resolve,reject){ console.log("ajaxC start!"); setTimeout(()=>{ console.log("ajaxC end!"); reject("iii"); },Math.random()*2000) } new MyPromise(ajaxA).then(function(){ return new MyPromise(ajaxB); }).then(ajaxC).catch(function(e){ console.log(e); }) </script>
//Promise实现原理
// 实例方法
// then
// catch
// new P( 函数 ).then(functon(){}).then(function(){})
// let p = new MyPromise();
// p.resolve(); //不允许的
// 静态方法
// all
// race
// 属性
// status : pending / resolved / rejected
// resolve / reject
// 要求, 每个promise对象, status状态初始为pending
// 该属性不可直接修改,只能通过回调 修改
// 并且,状态一旦被修改, 不可逆.
// 执行目标函数时, 需要传参数, resolve, reject
function
MyPromise
(
main
){
let status
=
"
pending
"
;
//MyPromise刚被创建的初始化状态
let listTask
= []
;
//定义一个数组,用于存储.then()里函数
let exceptionHander
=
null
;
//用于捕捉错误
function
resolve
(
msg
){
//如果函数返回resolve()方法则调用
if(status
==
"
pending
")
{
//如果状态为pending则执行,否则不执行,程序结束
status
=
"
resolve
"
;
//函数顺利执行完将promise状态改为resolve
let next
= listTask
.
shift()
;
//拿出数组中第一个
let newp
=
next(msg)
;
if(newp
instanceof
MyPromise)
{
//如果拿出来函数也new MyPromise,则执行
listTask
.
forEach(
t
=>
{
newp
.
then(t)
;
//例 new MyPromise(ajaxB).then(function(){ return new MyPromise(ajaxC)}).then(ajaxD).catch(function(e){console.log(e)})
})
}
}
}
function
rejected
(
msg
){
//如果返回rejected,执行此函数
if(status
==
"
pending
")
{
//如果当前MyPromise状态为pending
status
=
"
rejected
"
;
//更改状态为rejected ,抛出异常,输出方法里的msg
if(exceptionHander)
{
//有catch则调用,否则报错
}
else
{
exceptionHander(msg)
;
}
}
}
this
.
then
=
function
(
task
){
//讲第一个new Promise后面所有.then加入listTask数组里
console
.
log(
this)
;
listTask
.
push(task)
;
return
this
;
//返回,循环加入
},
this
.
catch
=
function
(
fn
){
exceptionHander
= fn
;
}
this
.
getStatus
=
function
(){
return status
;
}
main(resolve
,rejected
.
bind(
this))
;
//给第一个函数两个参,函数也需要设置两个参数接收,否则报错
}
MyPromise
.
all
=
function
(
args
){
let count
=
0
;
let task
=
null
;
function
isOver
(){
count
++
;
if(count
== args
.length)
task()
;
}
args
.
forEach(
p
=>
{
p
.
then(isOver)
;
})
return
then(fn)
{
task
= fn
;
}
}