经典面试题第九更---Promise养猪场

前言:
    🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈
    🏠 个人主页:  Morning的主页
    📕系列专栏: 前端面试备战
    📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流
    🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

 

 前言

Promise对于我自己来说,一直都处于一个仅限于只会用的状态,什么时候用,有什么好处等等差太远,根本不了解它。就只是在做项目中照葫芦画瓢的用Promise写需求。

但是在意识到JS基础重要性后,我就开始恶补JS基础,也就是这个专栏的来源。在学习之后,我与大家来分享一下我的心得

1.含义

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

而这个结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

而且状态改变过之后就不会再发生改变。Promise对象的状态改变,只有两种可能:pending变为fulfilled  和      从pending变为rejected

大白话来讲,Promise像是一个养猪场。new Promise就相当于养了一头新🐖,这头猪猪正在成长中(pending),这个🐖有两种结果,要么长大了(fulfilled),要么病死了(rejected)。二者只有一种可能

2.为甚么使用Promise

当一个请求需要依赖上一个请求返回结果的时候,就会形成类似这样的调用结构,我看见都瑟瑟发抖,又难看,又难维护。很容易出现回调地狱(Callback Hell)

于是Promise就诞生了,用于优雅的表达异步回调 

请求一(function(结果一){
        请求二(function(结果二){
            请求三(function(结果三){
                请求四(function(结果四){
                    ......
                })
            })
        })
    })

3.基本使用

Promise是一个构造函数,所以调用时通过new来使用,传入函数类型的参数

resolve函数的作用是,将Promise对象的状态从“进行中”变为“成功”(即从 pending 变为 resolved),并将运行成功的结果作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“进行中”变为“失败”(即从 pending 变为 rejected),并将报出的错误,作为参数传递出去。

new Promise((resolve,reject)=>{
        if(🐖长大了){
            resolve()
        }else{//🐖病死了
            reject()
        }
    })

4. then、catch、finally的诞生及静态方法

为了更好的控制下一步执行,Promise还拥有三个实例方法 then   catch    finally

then方法用来控制接下来干什么,支持链式调用。养了一头新🐖后,长大--->杀猪--->剃毛--->工厂加工猪肉--->火腿肠。then的执行必须依赖上一步的结果(比如想吃火腿肠就必须先让工厂加工),以上每一个过程都会出现两种结果,因此then又会接收两种结果(resolve对应成功 reject对应失败)。但是每一次都写reject就特别麻烦

于是诞生了catch方法,在.then()之后来.catch(),用来处理reject的情况,而且还可以监听resolve中的异常情况(监听以上任意过程的出错)

但是有时候无论是resolve还是reject(无论🐖长大了还是病死了),都需要执行一些方法,就诞生了finally方法 。

此外为了满足更多的开发需求,就诞生了一些静态方法

all:所有🐖都长大才执行

allSettled:所有🐖都有结果了就执行,无论死活

any:任意一头🐖养成就执行

race:任意一头🐖养成或病死了就执行

reject:返回一个状态为rejected的Promise对象

resolve: 

5.简单实例

const promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    if (Math.random() < 0.5) {
      resolve('success');
    } else {
      reject('error');
    }
  }, 1000);
});
 
promise.then(result => {
  console.log(result);
  console.log('第一次then执行成功');
}).then(()=>{
    console.log('第二次then执行成功,Promise.then()后的结果仍然是一个Promise,可以进行链式调用');
}).catch(error => {
  console.log(error);
  console.log('第一次then执行失败,直接跳到catch');
}).finally(()=>{
    console.log('无论执行成功与否,finally都会执行');
});

两种返回结果

 

6.实现一个简单Promise

const  PENDING ='pending'
const  RESOLVED='resolved'
const  REJECTED='rejected'
function myPromise(fn){
    const that=this;
    this.state=PENDING;
    //value用来保存resolve或reject中传入的值
    this.value=null
    //用来保存then中的回调.因为执行完Promise,状态有可能还是等待中
    that.resolvedCallback=[]
    that.rejectedCallback=[]

    function resolve(value){
        //两个函数开始要先判断当前状态是否为等待中
        if(that.state===PENDING){
            that.state=RESOLVED
            that.value=value
            //遍历数组回调并执行
            that.resolvedCallback.map(cb=>cb(that.value))
        }
    }
    function reject(value){
        //两个函数开始要先判断当前状态是否为等待中
        if(that.state===PENDING){
            that.state=REJECTED
            that.value=value
            //遍历数组回调并执行
            that.resolvedCallback.map(cb=>cb(that.value))
        }
    }
    try{
        fn(resolve,reject)
    }catch(e){
        reject(e)
    }
}
//实现then函数
myPromise.prototype.then=function(onFulfilled,OnRejected){
    const that=this
    //判断两个参数是否为函数类型,因为两个参数是可选参数
    onFulfilled=typeof onFulfilled==='function'?onFulfilled:v=>v
    OnRejected=typeof OnRejected==='function'?OnRejected:e=>{throw e}
    //
    if(this.state===PENDING){
            this.resolvedCallback.push(onFulfilled)
            this.rejectedCallback.push(onFulfilled)
    }
    if(this.state===RESOLVED){
        onFulfilled(that.value)
    }
    if(this.state===REJECTED){
        OnRejected(that.value)
    }
}

//应用
const promise = new myPromise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    if (Math.random() < 0.5) {
      resolve('success');
    } else {
      reject('error');
    }
  }, 1000);
});
 
promise.then(result => {
  console.log(result);
  console.log('then执行成功');
});

文章灵感:阮一峰的Promise                10分钟彻底掌握手写promise及原理,难倒面试官!_哔哩哔哩_bilibili

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏茂林别干饭了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值