首页 > 其他分享 >如何手写一个promise函数

如何手写一个promise函数

时间:2023-05-11 17:55:10浏览次数:32  
标签:resolve const 函数 .# state promise reject 手写 data

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECT = 'rejected'; 

class MyPromise {

    #state = PENDING
    #result = undefined
    #handler = []

    constructor(executor){
        const resolve = (data) => {
            this.#changeState(FULFILLED, data)
        }
        const reject = (err) => {
            this.#changeState(REJECT, err)
        }

        try{
            executor(resolve, reject)
        }
        catch(err){
            reject(err)
        }
    }
    #changeState(state, result){
        if(this.#state !== PENDING) return
        this.#state = state
        this.#result = result

        this.#run()

    }
    // 判断这个callback是不是一个promise
    #isPromiseLike(value){
        return typeof value == 'object' && typeof value.then == 'function'
        // return value instanceof MyPromise || value[Symbol.for('nodejs.runtime.asm.promise')] instanceof MyPromise || value[Symbol.for('nodejs.runtime.asm.promise.constructor')] instanceof MyPromise;
    }
    // 手动将函数添加到微任务
    #runMicroTask(fun){
        if (typeof MutationObserver !== 'undefined') {
            const textNode = document.createTextNode('0')
            const ob = new MutationObserver(fun)
            ob.observe(textNode, { characterData: true })
            textNode.data = '1'
          } else {
            process.nextTick(fun)
          }
    }
    #runCall(callBack, resolve, reject){

        // then中的回调需要放在微队列中
        this.#runMicroTask(() => {
            // console.log('www',callBack, resolve, reject)
            if (typeof callBack === "function") {
                
                try{
                    const data = callBack(this.#result);
                    // 判断这个data返回的是不是一个promise
                   if(this.#isPromiseLike(data)){
                       
                       data.then(resolve, reject)
                       
                    } else resolve(data)
                }
                catch{
                    reject(this.#result)
                }
    
            } else {
                const settled = this.#state === FULFILLED ? resolve : reject
                settled(this.#result) //链式回调穿透
            }
        })
    }
    #run(){
        if (this.#state === PENDING) return
        
        while(this.#handler.length){
            const {onFulfilled, onRejected, resolve, reject} = this.#handler.shift()
    
            if (this.#state === FULFILLED) {
                this.#runCall(onFulfilled, resolve, reject)
                
            } else {
                this.#runCall(onRejected, resolve, reject)
            }

        }
    }

    then(onFulfilled, onRejected){
        return new MyPromise((resolve,reject) => {

          this.#handler.push({
            onFulfilled,
            onRejected,
            resolve,
            reject
          })

          this.#run() //recursion to avoid stack overflow.

        })

       
    }
}

、
执行:
const p = new MyPromise((resolve,reject) => {
    resolve(1)
}) //constructor for a promise
p.then((val) => {
    console.log('data1',val)
    return 123
}).then((data) => {
    console.log('data2',data)
})

输出:
[Running] node "d:\console\utils\myPromise.js"

data1 1
data2 123

 

标签:resolve,const,函数,.#,state,promise,reject,手写,data
From: https://www.cnblogs.com/xuhuang/p/17391807.html

相关文章

  • 移相全桥控制算法的C代码+仿真模型,电压单闭环,电压外环电流内环双闭环,采用S函数调用的
    移相全桥控制算法的C代码+仿真模型,电压单闭环,电压外环电流内环双闭环,采用S函数调用的方式直接在simulnik环境下对C代码进行仿真。已经在样机上验证过,波形非常好!ID:2560680754811245......
  • 使用 Lambda 函数将 CloudWatch Log 中的日志归档到 S3 桶中
    >作者:[SRE运维博客](https://www.cnsre.cn/)>博客地址:[https://www.cnsre.cn/](https://www.cnsre.cn/)>文章地址:[https://www.cnsre.cn/posts/221205544069/](https://www.cnsre.cn/posts/221205544069/)>相关话题:[https://www.cnsre.cn/tags/aws/](https://www.cnsr......
  • LSTM算法做时间序列的预测,使用matlab自带的LSTM工具箱函数,预测精度很高,网络参数最优化
    LSTM算法做时间序列的预测,使用matlab自带的LSTM工具箱函数,预测精度很高,网络参数最优化处理,误差评价指标计算。ID:6768660696244807......
  • EKF_SOC_Estimation函数使用二阶RC等效电路模型估算电池的端电压(Vt)和充电状态(SOC)。
    EKF_SOC_Estimation函数使用二阶RC等效电路模型估算电池的端电压(Vt)和充电状态(SOC)。该功能可以使用扩展卡尔曼滤波器(EKF)或自适应扩展卡尔曼滤波器(AEKF)。用户还可以选择估算-20℃至40℃的SOC。其中包括一个样品LA92行驶周期,电池参数(包括内部电阻)和Turnigy电池的SOC-OCV曲线。SOC......
  • tensorflow实现mnist手写数字识别
    1.softmax函数在数学,尤其是概率论和相关领域中,归一化指数函数,或称Softmax函数,是逻辑函数的一种推广。它能将一个含任意实数的K维向量z“压缩”到另一个K维实向量σ(z)中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。该函数多用于多分类问题中。在多项逻辑回归和......
  • python基础学习-hashlib - 哈希函数模块
    hashlib-哈希函数模块参考地址:Python-Core-50-Courses/第20课:Python标准库初探.mdatmaster·jackfrued/Python-Core-50-Courses(github.com)待补充......哈希函数又称哈希算法或散列函数,是一种为已有的数据创建“数字指纹”(哈希摘要)的方法。哈希函数把数据压缩成摘要,对......
  • #PowerBi 10分钟学会,以X为结尾的聚合函数
    前言在PowerBI中,我们经常需要对数据进行聚合计算,比如求和、求平均、求最大值等。PowerBI提供了一系列的聚合函数,可以用来对表中列的值进行聚合然后返回一个值。这些函数通常只需要一个参数,就是要聚合的列名。如SUM(‘销售表’[销量]),就是求销售表里的销量总和。但是有时候,我......
  • 父类析构函数一定要使用析构函数的原因
    如果基类的析构函数不是虚函数,在删除一个指向派生类对象的基类指针时,只有基类的析构函数被调用,而派生类的析构函数不会被调用。这可能导致资源泄漏,未正确释放派生类分配的内存等问题。当基类的析构函数被声明为虚函数时,C++运行时会根据实际的对象类型调用相应的析构函数。这意味......
  • Oracle之table()函数的使用,提高查询效率
    目录一、序言二、table()函数使用步骤三、table()具体使用实例3.1table()结合数组使用3.2table()结合PIPELINED函数(这次报表使用的方式)3.3table()结合系统包使用一、序言前段时间一直在弄报表,快被这些报表整吐了,然后接触到了Oracle的table()函数。所以今天把table()函数的......
  • 单链表——追加函数(有无懂的大佬解答一下why不加强制类型过不去)
    #include<bits/stdc++.h>usingnamespacestd;typedefstruct{intid;stringname;}Data;typedefstruct{ DatanodeData; structNode*nextNode;}CLtype;//追加链表CLtype*CLAddEnd(CLtype*head,Datanodedata){CLtype*node,*htemp; if(!(node=(CLt......