zoukankan      html  css  js  c++  java
  • 从零实现一个promise

    切入点从场景描述出发,即先定义好我们要实现的功能

    执行器函数

    构造函数入参 executor 自执行函数。会在在 new 的时候同步执行,传入 resolve 和 reject 状态扭转函数。自执行函数内部根据异步任务执行结果(成功或失败)调用状态扭转函数,把状态传递给后续的 then。

    状态转化

    promise 有三种状态,默认是 pending,成功之后为 fulfilled,失败之后为 failed。且状态一旦发生改变,之后不可再改变也不可逆

    then 方法

    then 方法接受两个函数,表示成功、失败状态下的回调函数。回调函数中 return 中值会当作参数传给后续的then。以此实现链式调用。

    判断一个变量是否为 promise 需要两个条件,首先要是对象,然后对象上有 then 方法,以此得出 then 执行的结果也是一个 promise

    https://www.houdianzi.com/ logo设计公司

    实现

    class Promise {
        constructor(executor){
            this.status = 'pending',
            this.value = undefined;
            this.reason = undefined;
            this.onFulfilled =undefined;
            this.onRejected = undefined;
            this.onFulfilledList = [];
            this.onRejectedList = [];
            try {
                executor(this.resolve, this.reject);
            } catch(e) {
                this.reject(e)
            }
        }
        resolve(value){
            if(this.status == 'pending') {
                this.status = 'fullfilled';
                this.value = value;
                this.onFulfilledList.forEach(item => item())
            }
        }
        reject(reason){
            if(this.status == 'pending') {
                this.status = 'rejected';
                this.reason = reason;
                this.onRejectedList.forEach(item => item())
            }
        }
        then(onFulfilled, onRejected){
            // then 之后要返回一个新的 promise
            let result;
            if(this.status == 'fullfilled' && onFulfilled) {
                result = onFulfilled(this.value)
                return Promise.resolve(result);
            }
    
            if(this.status == 'rejected' && onRejected) {
                result = onRejected(this.reason);
                return Promise.resolve(result);
            }
    
            if(this.status == 'pending') {
                onFulfilled && this.onFulfilledList.push(()=>onFulfilled(this.value));
                onRejected && this.onRejectedList.push(() => onRejected(this.reason));
            }
        }
    }
    
    Promise.resolve = function(value) {
        if(typeof value == 'object' && value.then) {
            return value;       
        } else {
            return new Promise((resolve, reject)=>{
                resolve(value)
            })
        }
    }
    
    Promise.all = function(list) {
        return new Promise((resolve,reject) => {
            let result = [];
            let count = 0;
            for(let i = 0; i < list.length; i++)  {
                if(typeof list[i] == 'object' && list[i].then) {
                    Promise.resolve(list[i]).then(data =>{
                        result[i] = data;
                        count++;
                    },reject)
                }else {
                    result[i] = list[i];
                    count++;
                }
            }
            if(count == list.length) {
                resolve(result);
            } 
        })
       
    }
    
    // Promise.race  同理,只要有一个成功,全部  resolve
    // Promise.finally 不管成功失败,传递的回调函数都会执行,执行之后仍然可以跟then
  • 相关阅读:
    【整理】互联网服务端技术体系:存储基础之数据存储与索引结构
    python基础之enumerate() 函数+ Counter类计数器
    介绍几个好用的Java库
    【GIS】BlenderGIS应用配置之一
    使任意同步库快速变asyncio异步语法的方式 ,run_in_executor
    mysql查看表行数
    mysql8.0使用mysqldump报错:Unknown table ‘column_statistics‘ in information_schema (1109)
    sysbench安装使用,结果信息分析
    【1.6】shell使用 -p -f 之类的参数
    右键新建项中添加Typora新建Markdown文件快捷选项
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/15149708.html
Copyright © 2011-2022 走看看