IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 实现一个符合promiseA+规范的promise -> 正文阅读

[JavaScript知识库]实现一个符合promiseA+规范的promise

关于异步的解决方案目前有四种:

  • callback(回调函数)
  • generato + co库
  • promise
  • async+await

promise的基本特点:

  1. promise代表的是承诺的意思 promise最核心的就是有三个状态,等待态(pending), 成功态(fulfilled)
    ,失败态(rejected)
  2. 状态只能从等待态改变成其他状态 ,不能从成功变成失败,也不能从失败变成成功
  3. 默认你传入的executor会立刻执行, 这个executor函数接受两个参数 resolve,reject 都是函数类型
  4. 在代码中发生异常也是会走失败的情况

封装基本的promise :

// 三个状态
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
class Promise {
    constructor(executor) { // 用户传入一个executor
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onResolvedCallbacks = []; // 存放成功的回调的
        this.onRejectedCallbacks = []; // 存放失败的回调的
        const resolve = (value) => {
            if (this.status === PENDING) {
                this.status = FULFILLED
                this.value = value;
                this.onResolvedCallbacks.forEach(fn=>fn());
            }
        }
        const reject = (reason) => {
            if (this.status === PENDING) {
                this.status = REJECTED
                this.reason = reason;
                this.onRejectedCallbacks.forEach(fn=>fn());
            }
        }
        try {
            executor(resolve, reject); 
        } catch (e) {
            reject(e);
        }
    }
    then(onFulfilled, onRejected) { 
        //调用then的时候来判断成功还是失败
        if(this.status ===FULFILLED ){
            onFulfilled(this.value);
        }
        if(this.status === REJECTED){
            onRejected(this.reason)
        }
        if(this.status === PENDING){
            this.onResolvedCallbacks.push(()=>{
                onFulfilled(this.value);
            });
            this.onRejectedCallbacks.push(()=>{
                onRejected(this.reason);
            })
        }
    }
}

测试验证:

let promise = new Promise((resolve,reject)=>{ 
    setTimeout(()=>{
      resolve('1111');
    },1500)
});
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})

封装完基本版本后,还存在的问题:
1.then不是异步的,如果直接调用resolve完后是同步执行,比如:

let promise = new Promise((resolve,reject)=>{ 
  resolve('1111');
});
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})
console.log('end');

结果是先输出:success 1111,再试end
2.我们newPromise 直接resolve了 ,会将resolve的参数传递到了下一次then中,then中传递的成功和失败的回调的返回值, 会决定下一个then 走成功还是失败,比如:

let promise2 = new Promise((resolve,reject)=>{
    resolve('ok')
})

promise2.then(data=>{
    return 'next'
},()=>{
    return 'fail'
}).then((data)=>{
    console.log('success',data)
},(err)=>{
    console.log('fail',err)
})

该代码输出的正确结果,应该是 success next,但输出却是报错的,因为then并没有返回值
在这里插入图片描述

进阶版promise实现:

const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
function resolvePromise(promise2, x, resolve, reject) {
    if (x) {
        try {
                resolve(x); 
        } catch (e) {
            reject(e); 
        }
    } else {
        resolve(x); // 这里直接成功即可 普通值的情况
    }
}
class Promise {
    constructor(executor) {
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onResolvedCallbacks = []; // 存放成功的回调的
        this.onRejectedCallbacks = []; // 存放失败的回调的
        const resolve = (value) => {
            if(value instanceof Promise){
                return value.then(resolve,reject)
            }
            if (this.status === PENDING) {
                this.status = FULFILLED
                this.value = value;
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        }
        const reject = (reason) => {
            if (this.status === PENDING) {
                this.status = REJECTED
                this.reason = reason;
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }
        try {
            executor(resolve, reject); 
        } catch (e) {
            reject(e);
        }
    }
    then(onFulfilled, onRejected) {
        let promise2 = new Promise((resolve, reject) => {
            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) { // 执行对应的回调时发生异常就执行promise2的失败
                        reject(e);
                    }
                }, 0);
            }
            if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) { // 执行对应的回调时发生异常就执行promise2的失败
                        reject(e);
                    }
                }, 0);
            }
            if (this.status === PENDING) {
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) { // 执行对应的回调时发生异常就执行promise2的失败
                            reject(e);
                        }
                    }, 0)
                });
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) { // 执行对应的回调时发生异常就执行promise2的失败
                            reject(e);
                        }
                    }, 0)
                })
            }
        });

        return promise2
    }
}

结果:

let promise = new Promise((resolve,reject)=>{ 
  resolve('1111');
});
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})
promise.then((value)=>{ 
    console.log('success',value)
},(reason)=>{ 
    console.log('fail',reason)
})
console.log('end');

能正确输出结果:在这里插入图片描述

let promise2 = new Promise((resolve,reject)=>{
    resolve('ok')
})

promise2.then(data=>{
    return 'next'
},()=>{
    return 'fail'
}).then((data)=>{
    console.log('success',data)
},(err)=>{
    console.log('fail',err)
})

正确输出结果:
在这里插入图片描述

当然上面进阶版的实现也不是最终完整版的,最终的版本会有很多类型判断,我也是把基本代码跑通了而已,面试的时候,基本版本就够用了,毕竟也不会给这么多时间你写,哈哈

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:27:11  更:2022-03-04 15:29:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:36:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码