理解Promise(手撕代码)

164 阅读3分钟

Promise真的是很实用的东西,对于像JS这种单线程编程来讲,真的在开发中有奇效!一般我也都是配合着axios一起服用。那话说回来,Promise究竟是干哈的捏?

其实Promise给我最直观的感受就是它能用同步的方式去写异步的代码。

在我们开发中,比如说我做了一个网站需要调用API的数据时,代码走到这一步了请求数据回来,然后我们拿到数据。看起来一切都很符合常规是吧,但是如果说因为一些不可抗拒因素,比如网速太慢,服务器卡顿等等问题导致你所请求的数据无法及时给你做出响应,那此时你的代码就会卡在这个地方,阻塞了后面代码的运行🙉但如果你拥有了Promise,还是一样的过程,但当卡在了同样的位置时,Promise的做法是把你的代码先托管(专业点说代理🤦‍♀️)起来,让后面的代码先运行吧,什么时候服务器响应的数据到达了客户端,那这时候Promise才会让你刚才的代码执行(就是调用Promise里的回调)。

大致了解这些以后,我们来聊聊Promise出现的原因是什么。在Promise还未出生🤣的时候,用JavaScript实现异步操作都是用回调嵌套回调去做的,如果像我们个人开发一个博客网站这种简单的还好说,一旦项目庞大起来,里面逻辑稍微复杂一些极容易出现回调地狱的问题,如下:

setTimeout(function(){
    console.log('ko ')
    setTimeout(function(){
        console.log('no ')
        setTimeout(function(){
            console.log('dio ')
            setTimeout(function(){
                console.log('da')
            },1000)
        },1000)
    },1000)
},1000)

这还只是套了三个,要是套个几十个,先不说效率的问题,就这代码看着就头疼吧,可读性极差。而且一有啥问题那只能硬着头皮一点点去找。反而同样的问题,如果用Promise就轻松了太多,如下:

function fn(str){
    const p = new Promise((resolve,reject)=>{
        let flag = true
        setTimeout(function(){
            if(flag){
                resolve(str)
            }else{
                reject(str)
            }},1000)
    })
    return p
}

fn('ko').then((data)=>{
    console.log(data + '')
    return fn('no')
}).then((data)=>{
    console.log(data + '')
    return fn('dio')
}).then((data)=>{
    console.log(data + '')
    return fn('da')
}).then((data)=>{
    console.log(data + '')
}).catch(()=>{
    console.log('这就是我的逃跑路线!')
})

大概就说这么多吧,到了主题手撕代码,我就不多b×2了。直接上代码。

const PENDING ='pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromiss {
    // 创建实例时自动触发
    constructor(executor){
        executor(this.resolve,this.reject);
    }
    
    status = PENDING;
    value = null;
    reason = null;
    onFulfilledCallback = null;
    onRejectedCallback = null;
    resolve = (value)=>{
    	if(this.status === PENDING){
            this.status = FULFILLED;
            this.value = value;
        	this.onFulfilledCallback && this.onFulfilledCallback(value);
        }
    }
    reject=(error)=>{
        if(this.status === PENDING){
            this.status = REJECTED;
            this.reason = reason;
            this.onRejectedCallback && this.onRejectedCallback(reason);
        }
    }
    then(onFulfilled,onRejected){
        if(this.status === FULFILLED){
            onFulfilled(this.value);
        }
        if(this.status === REJECTED){
            onRejected(this.reason);
        }
        if(this.status === PENDING ){
            this.onFulfilledCallback = onFulfilled;
            this.onRejectedCallback = onRejected;
        }
    }
}

这里只是写了Promise的核心,当然它本身还有很多东西,比如Promise.all()Promise.race()

详细更多内容我建议看看这篇文章blog.csdn.net/asd24372520…

还有这篇文章,就是咱们掘金大神写的,从底层到实现讲的十分nice 从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节 - 掘金 (juejin.cn)

当然本篇文章可能也有不对的地方或者不严谨的地方,欢迎大家在评论区和平交流🤝🤝🤝🤝


参考文章:

漫谈promise使用场景 - 简书 (jianshu.com)

(80条消息) 什么是回调地狱?怎么解决回调地狱_殿君不是殿军的博客-CSDN博客_什么是地狱回调