今天根据之前的es6类的写法手写一个自己的Promise,我们先看一下原生的Promise写法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
let createPromise=new Promise((resolve,reject)=>{
$.ajax({
url:'./ajax.json',// 同级目录下新建一个json文件用以访问
dataType:'json',
success(data){
resolve(data)
},
error(err){
reject(err)
}
})
});
createPromise.then((data)=>{
console.log(data)
},(err)=>{
console.log(err)
})
</script>
</html>
我们可以看到我们的Promise对象使用new 生成,并且接收一个函数,参数也为函数, 因为在后面执行了resolve();并且有一个then方法,参数与上面一致,所以我们可以这样写,直接上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
// 声明类和then方法
class MyPromise {
constructor(fn) {
this.status = ''; // 记录函数执行的状态
this.queue = []; // 等待队列
this.successResult = ''; // 接收成功函数的参数
this.failResult = ''; // 接收失败函数的参数
fn((...arg) => {
// 代表成功的函数
this.status = 'success';
this.successResult = arg;
// 此时此函数已完成检查队列中是否存在元素,存在则说明 then方法已提前调用,方法还未被执行,所以我们在这里执行
this.queue.forEach((fn) => {
fn.fn1(arg)
})
}, (...arg) => {
// 代表失败的函数
this.status = 'fail';
this.failResult = arg;
this.queue.forEach((fn) => {
fn.fn2(arg)
})
}); // 执行函数 函数参数也为两个函数
}
then(fn1, fn2) {
/*
fn1 代表成功函数 fn2 代表失败函数
执行then时如果函数的状态值已改变 直接调用函数并将存储的值传递进去 如果此时值还未改变,将参数放入队列
*/
if (this.status == 'success') {
fn1(this.successResult)
} else if (this.status == 'fail') {
fn2(this.failResult)
} else {
this.queue.push({
fn1,
fn2
})
}
}
}
let createPromise = new MyPromise((resolve, reject) => {
$.ajax({
url: './ajax.json', // 同级目录下新建一个json文件用以访问
dataType: 'json',
success(data) {
resolve(data)
},
error(err) {
reject(err)
}
})
});
createPromise.then((data) => {
console.log(data)
}, (err) => {
console.log(err)
})
</script>
</html>