Promise是ES6中最受欢迎的新特性,它提供了一种不使用回调函数的优雅异步编程代码实践。
使用方法
Promise是一个类,其构造函数接受一个带有两个参数resolve和reject的函数。该函数的内容便是起始函数,在Promise声明后会被,立即执行,如果成功执行,则会调用resolve函数,否则会调用reject。对应的,一个Promise的三个状态分别是pending、fulfilled和rejected。
运行Promise的构造函数会返回一个Promise,其最常用的方法便是then、catch和finally。通常来讲我们不会经常调用resolve和reject,而是通过Promise的链式调用来进行操作。如果想在链式调用中传递参数,可以给res传参或者在then的函数体中返回。
const promise1 = new Promise((res,rej)=>{
res('a');
})
.then((x)=>{
console.log(x);
return 'b';
})
.then((y)=>{
console.log(y);
})
// a b
实现原理
我们都知道,在出现Promise前,JavaScript一直是使用回调函数来进行异步调用。而Promise便是一种对回调函数的包装。
- 类必须要有一个
callbacks属性,来存储所有后续调用的函数 then方法把需要调用的函数塞进callbacks中,别忘了返回一个新的Promise以供链式调用- 构造函数中直接按顺序调用
callbacks中的所有函数即可,别忘了在异步操作执行成功后调用resolve函数以及绑定对应的this - 为了保证能够完整的链式调用,我们需要给每个
Promise函数增加一个状态,并且保存每一步调用的结果,确保函数能够按我们想要的顺序调用。 - 对于传参,我们再添加一个
value属性就可以。
class myPromise{
state = 'pending';
value = null;
callbacks =[];
constructor(fn){
fn(this.resolve.bind(this));
};
then(func){
if(this.state === 'pending'){
this.callbacks.push(func);
}else{
func(this.value);
}
return this;
}
resolve(value){
this.state = 'fulfilled';
this.value = value;
this.callbacks.forEach((func)=>{
func(args);
})
};
}
const promise1 = new myPromise((res)=>{
console.log(0);
res();
})
.then(()=>{
console.log(1);
})
.then(()=>{
console.log(2);
})
// 0 1 2