【JS】把Promise手写明白!


就是说,把这个最爱考的手写系列给它整明白!总结加理解加多复习,我就不信还能有什么别的花样!

先介绍一下promsie的特点,三个状态pending、reject、fullfilled(resolved),状态只能从pending到另外两个,一经生成不可再改变,然后具有.then、.finally、.all、.race等函数进行使用

  • 抽象表达:

    Promise 是一门新的技术(ES6 规范)
    Promise 是 JS 中进行异步编程的新解决方案
    备注:旧方案是单纯使用回调函数

  • 具体表达:

    从语法上来说: Promise 是一个构造函数
    从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/
    失败的结果值

  • 为何要用promsie?
    1、指定回调函数的方式更加灵活
    2、支持链式调用,解决回调地狱的问题
    在这里插入图片描述

//一个普通的promise的使用

const p = new Promise((resolve,reject) => {
   
    setTimeout(() => {
   
        let n = Math.random()*100;
        if(n < 30){
   
            resolve(n);
        }else{
   
            reject('errrro发生错误');//返回的是一个prmise对象,且状态设置为失败,值为n
        }
    },1000)
})

console.log(p)

p.then((value) => {
   
    console.log('成果'+value)
},(err) => {
   
    console.log('shibai'+err)
})

所以手写的就要实现基本的功能,一个构造promise,resolve、reject回调函数,返回promise还要支持then的调用

手写Promsie函数

const promiseA = new Promise( (resolve,reject) => {
   
    resolve(777);
});
  • 传入了一个函数,而且这个函数被立即执行,不仅如此,这个函数还会立即执行resolve和reject。说明构造函数里有resolve和reject方法。因此我们可以初步实现:
  • 每个promise都有一个状态可能为pending或resolved,rejected。而且初始状态都为pending。因此需要添加个status来表示当前promise的状态.。并且每个promise有自己的data。
  • 不管是Promise原型对象上的方法还是Promise函数对象上的方法 ,它们的执行结果都将返回一个Promise对象
// 例1
var promise = new Promise((resovle,reject)=>{
   
    
})

promise.then(resolve=>{
   },reject=>{
   })

这种情况,当状态为pending的时候,要把then里面的回调函数保存起来,所以需要一个callbacks数组,等prmsie里面的resolve或足额reject之后再执行;

那么then函数是如何把传入的回调收集起来的,就是叛党当前promsie的状态是否为pending

举一个例子

// 例2
var promise = new Promise((resolve,reject)=>{
   
    setTimeout(function () {
   
        resolve(1)
    })
})

promise.then(
    value=>{
   console.log(value)},
    err=>{
   console.log(err)}
    )
  • 先执行new Promise里的代码,然后发现个定时器,js线程将定时器交给定时器线程处理,2. 然后继续执行下面的代码,发现是then,而且当前的promise还是pending的状态。就把then里的回调函数放到callbacks中。
  • 5秒后定时器线程将定时器里的回调函数(也就是宏任务)放到消息队列中,js线程在消息队列里发现了这个宏任务,就把它拿来执行。- - 执行这个宏任务,就执行了resolve(1),此时promise的callbacks里的回调被执行。并将当前promise状态改为resolved。然后这个1也会被 保存到当前promise对象中

那怎么实现resolve呢?依旧上面的描述,就知道resovle的功能是执行callbacks里的函数,并保存data,并将当前promise状态改为resolved。所以我们可以这么实现

执行到then时,promise可能会是pending状态,此时就要把then里的回调函数保存起来,也可能会是resolved或者rejected状态,此时就不用把回调保存起来,直接执行onResolved或onRejected方法。注意是异步执行。而且是做为微任务的,这里我们简单的用setTimeout来实现就好了。

function Promsie(callback) {
   
    this.state = PENDING;
    this.value = null;
    this.resolvedCallbacks = []
    this.rejectedCallbacks = []

    callback(value => {
   
        if(this.state == PENDING){
   
            this.state = RESOLVED
            this.value = value
            this.resolvedCallbacks
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值