前端积累 | Promise原理及实现

110 阅读2分钟

Promise是ES6中最受欢迎的新特性,它提供了一种不使用回调函数的优雅异步编程代码实践。

使用方法

Promise是一个类,其构造函数接受一个带有两个参数resolvereject的函数。该函数的内容便是起始函数,在Promise声明后会被,立即执行,如果成功执行,则会调用resolve函数,否则会调用reject。对应的,一个Promise的三个状态分别是pendingfulfilledrejected

运行Promise的构造函数会返回一个Promise,其最常用的方法便是thencatchfinally。通常来讲我们不会经常调用resolvereject,而是通过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