JavsScript系列-Promise的function写法
JS是单线程非阻塞的,解决非阻塞就需要通过回调来实现
Promise只是视觉上看起来是同步的,其实实现的本质依然是异步的,只是借助异步事件回调,通过then方法产生链式调用,看起来就是按顺序执行。
- 在Promise的另一篇文章中,我们使用class的写法探究了Promise的原理,本文中,我们使用function的写法来实现一个简单的Promise
实现
// 定义一个Promise, 接收一个函数作为参数
function Promise(callbalk){
this.state = 'pending' // Promise A+规范的三个状态:pending, resolved,rejected;
this.data = null; // Promise 维护一个data;
this.onthen = []; // then方法收集的回调队列;
this.funIndex = 0;
this.onReject = function(error) {
throw error;
}
// 异步执行初始函数
setTimeout(function() {
callback && callback(this.resolve.bind(this), this.reject.bind(this));
}.bind(this))
return this; // Promise返回其自身;以便找到then方法
}
由JS事件循环机制可以得知,then方法属于微任务,处于宏任务队列中,所以首次会先执行微任务,then方法内部将回调函数推入onthen数组中。
Promise.prototype.then = function(callback) {
this.onthen.push(callback);
return this;
}
同时,resolve方法需要在内部执行onthen中的方法,并继续返回当前Promise对象
Promise.prototype.resolve = function(data) { // data是异步执行完成后的数据
this.state = 'resolved';
this.data = data;
setTimeout(function() {
for(let i = this.funIndex, i < this.onthen.length; this.funIndex++){
let callback = this.onthen.shift();
this.data = callback(this.data); // resolve的返回值,保存在this.data中
}
}.bind(this))
return this;
}
reject方法也需要返回当前的Promise对象,同时执行onReject函数,用于错误捕获
Promise.prototype.reject = function(error) {
this.state = 'rejected';
this.onReject(error);
return this;
}
catch方法用来捕获错误,当错误被捕获时,Promise的状态应该被清零
Promise.prototype.catch = function(callback) {
this.onthen = [];
this.onReject = callback;
return this;
}
测试
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000);
});
p1.then((res) => {
console.log(res);
return 2;
})
.then((res) => {
console.log(res);
return 3;
})
.then((res) => {
console.log(res);
});
\