Javascript笔试题目(六)

news2025/1/18 18:53:07

 1.如何使用JS实现Promise 对象?请写出具体代码

Promise其实也不难-CSDN博客

Javascript 手写一个Promise_javascript中手写promise ?-CSDN博客

Promise其实也不难-CSDN博客

题目要求我们使用JavaScript实现一个Promise对象。对此我们可以基于Promise/A+规范的要求进行实现Promise/A+规范是对Promise行为的详细描述确保不同的Promise 实现可以互操作。实现一个符合Promise/A+规范的Promise对象需要处理以下几个核心概念:
1)三种状态: pending (进行中)、fulfilled (已成功)、rejected (已失败)
2)状态不可逆:状态一旦从pending转变为fulfilled 或rejected,就不可再改变。

3 ) then方法:用于注册回调函数,处理Promise的成功值或失败原因。
4)异步执行:回调函数需要异步执行。

class MyPromise {
    constructor(executor) {
        this.state = 'pending'; // 初始状态
        this.value = undefined; // 成功值
        this.reason = undefined; // 失败原因
        this.onFulfilledCallbacks = []; // 成功回调队列
        this.onRejectedCallbacks = []; // 失败回调队列

        const resolve = (value) => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
                this.onFulfilledCallbacks.forEach((callback) => callback());
            }
        };

        const reject = (reason) => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;
                this.onRejectedCallbacks.forEach((callback) => callback());
            }
        };

        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    then(onFulfilled, onRejected) {
        onFulfilled =
            typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected =
            typeof onRejected === 'function'
                ? onRejected
                : (reason) => {
                      throw reason;
                  };

        const promise2 = new MyPromise((resolve, reject) => {
            if (this.state === 'fulfilled') {
                setTimeout(() => {
                    try {
                        const x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                }, 0);
            } else if (this.state === 'rejected') {
                setTimeout(() => {
                    try {
                        const x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                }, 0);
            } else if (this.state === 'pending') {
                this.onFulfilledCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    }, 0);
                });

                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    }, 0);
                });
            }
        });

        return promise2;
    }
}

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise'));
    }

    let called = false;
    if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        try {
            const then = x.then;
            if (typeof then === 'function') {
                then.call(
                    x,
                    (y) => {
                        if (called) return;
                        called = true;
                        resolvePromise(promise2, y, resolve, reject);
                    },
                    (r) => {
                        if (called) return;
                        called = true;
                        reject(r);
                    }
                );
            } else {
                resolve(x);
            }
        } catch (error) {
            if (called) return;
            called = true;
            reject(error);
        }
    } else {
        resolve(x);
    }
}

// 使用示例
const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('Success');
    }, 1000);
});

promise
    .then((value) => {
        console.log(value); // 输出: 'Success'
        return 'Next success';
    })
    .then((value) => {
        console.log(value); // 输出: 'Next success'
    })
    .catch((error) => {
        console.error(error);
    });

 

const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('First success');
    }, 1000);
});

promise
    .then((value) => {
        console.log(value); // 输出: 'First success'
        return 'Second success';
    })
    .then((value) => {
        console.log(value); // 输出: 'Second success'
        return new MyPromise((resolve, reject) => {
            setTimeout(() => {
                resolve('Third success');
            }, 1000);
        });
    })
    .then((value) => {
        console.log(value); // 输出: 'Third success'
    })
    .catch((error) => {
        console.error(error);
    });

const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject('Error occurred');
    }, 1000);
});

promise
    .then((value) => {
        console.log(value);
    })
    .catch((error) => {
        console.error('Caught error:', error); // 输出: 'Caught error: Error occurred'
    });

MyPromise.prototype.finally = function (callback) {
    return this.then(
        (value) => MyPromise.resolve(callback()).then(() => value),
        (reason) =>
            MyPromise.resolve(callback()).then(() => {
                throw reason;
            })
    );
};

// 使用示例
const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('Success');
    }, 1000);
});

promise
    .then((value) => {
        console.log(value); // 输出: 'Success'
    })
    .finally(() => {
        console.log('Finally executed'); // 输出: 'Finally executed'
    });

MyPromise.resolve = function (value) {
    return new MyPromise((resolve, reject) => {
        resolve(value);
    });
};

MyPromise.reject = function (reason) {
    return new MyPromise((resolve, reject) => {
        reject(reason);
    });
};

// 使用示例
MyPromise.resolve('Resolved value').then((value) => {
    console.log(value); // 输出: 'Resolved value'
});

MyPromise.reject('Rejected reason').catch((reason) => {
    console.error(reason); // 输出: 'Rejected reason'
});

2.如何使用JS实现Promise的then方法?请写出具体代码

在 JavaScript 中,Promise 的 .then() 方法是用于处理 Promise 对象解决(resolve)或拒绝(reject)后的结果。Promise 构造函数本身并不直接提供 .then() 方法的实现,但你可以通过创建一个自定义的类来模拟 Promise 的行为,并在这个类中实现 .then() 方法。

然而,通常我们不需要自己实现 Promise 类和它的 .then() 方法,因为 JavaScript 的原生 Promise 已经提供了这些功能。不过,为了教育目的,我可以展示一个简化的 MyPromise 类,它模拟了原生 Promise 的一部分行为,并实现了 .then() 方法。

请注意,这个示例是为了教学目的而简化的,并不包含原生 Promise 的所有功能和错误处理机制。

class MyPromise {  
    constructor(executor) {  
        this.state = 'pending'; // 初始状态为pending  
        this.value = undefined; // 保存resolve的值  
        this.reason = undefined; // 保存reject的原因  
        this.onFulfilledCallbacks = []; // 成功回调函数的数组  
        this.onRejectedCallbacks = []; // 失败回调函数的数组  
  
        const resolve = (value) => {  
            if (this.state === 'pending') {  
                this.state = 'fulfilled';  
                this.value = value;  
                this.onFulfilledCallbacks.forEach(fn => fn());  
            }  
        };  
  
        const reject = (reason) => {  
            if (this.state === 'pending') {  
                this.state = 'rejected';  
                this.reason = reason;  
                this.onRejectedCallbacks.forEach(fn => fn());  
            }  
        };  
  
        try {  
            executor(resolve, reject);  
        } catch (error) {  
            reject(error);  
        }  
    }  
  
    then(onFulfilled, onRejected) {  
        if (this.state === 'fulfilled') {  
            onFulfilled(this.value);  
        } else if (this.state === 'rejected') {  
            onRejected(this.reason);  
        } else {  
            // 如果Promise还在pending状态,将回调函数添加到相应的数组中  
            this.onFulfilledCallbacks.push(() => onFulfilled(this.value));  
            this.onRejectedCallbacks.push(() => onRejected(this.reason));  
        }  
  
        // 注意:这里的实现没有返回一个新的Promise,也没有处理链式调用和异步执行的情况  
        // 这是一个非常简化的版本,仅用于演示目的  
        // 在实际使用中,你应该返回一个新的Promise来处理这些情况  
    }  
}  
  
// 使用MyPromise的示例(但请注意,这个示例不会按预期工作,因为它缺少了许多关键功能)  
// 下面的代码只是为了展示如何调用.then()方法,但它不会正确地处理异步操作  
const myPromise = new MyPromise((resolve, reject) => {  
    setTimeout(() => {  
        resolve('Success!');  
    }, 1000);  
});  
  
myPromise.then(value => {  
    console.log(value); // 预期输出: Success!,但实际上这个示例不会工作  
});  
  
// 要使上面的代码工作,你需要实现一个能够处理异步回调和链式调用的.then()方法  
// 这通常涉及到返回一个新的Promise,并在适当的时机调用resolve或reject

然而,上面的 MyPromise 类并没有正确地实现 .then() 方法,因为它没有处理异步回调和链式调用。在真实的 Promise 实现中,.then() 方法会返回一个新的 Promise,这个新的 Promise 会根据传入的 onFulfilled 或 onRejected 回调函数的执行结果来解决或拒绝。

为了正确地实现 .then() 方法,你需要更复杂的逻辑,包括:

  1. 创建一个新的 Promise
  2. 在 onFulfilled 或 onRejected 回调函数中,根据执行结果来解决或拒绝这个新的 Promise
  3. 确保 onFulfilled 和 onRejected 回调在适当的时机(即原始 Promise 解决或拒绝后)以异步方式执行。

3.如何使用JS实现Promise的all方法?请写出具体代码

function myPromiseAll(promises) {  
    return new Promise((resolve, reject) => {  
        const results = []; // 用于存储每个Promise的解决值  
        let count = 0; // 已解决的Promise计数器  
  
        // 遍历promises数组,为每个Promise添加.then()处理器  
        promises.forEach((promise, index) => {  
            promise.then(  
                value => {  
                    results[index] = value; // 存储解决值  
                    count++; // 增加计数器  
                    // 如果所有Promise都已解决,则调用resolve  
                    if (count === promises.length) {  
                        resolve(results);  
                    }  
                },  
                reason => {  
                    // 如果有任何一个Promise被拒绝,则立即调用reject  
                    reject(reason);  
                }  
            );  
        });  
    });  
}  
  
// 使用myPromiseAll的示例  
const promise1 = Promise.resolve(1);  
const promise2 = Promise.resolve(2);  
const promise3 = Promise.resolve(3);  
  
myPromiseAll([promise1, promise2, promise3]).then(values => {  
    console.log(values); // 输出: [1, 2, 3]  
});  
  
// 另一个示例,其中一个Promise被拒绝  
const promise4 = Promise.resolve(4);  
const promise5 = Promise.reject('Error!');  
  
myPromiseAll([promise4, promise5]).catch(error => {  
    console.log(error); // 输出: Error!  
});

4.如何使用JS实现Promise的race方法?请写出具体代码

在 JavaScript 中,Promise.race 方法接受一个可迭代对象(通常是数组)作为输入,该对象包含多个 Promise 对象(或可转换为 Promise 的对象)。它返回一个新的 Promise,该 Promise 的解决(resolve)或拒绝(reject)状态由第一个解决或拒绝的输入 Promise 决定。如果第一个 Promise 解决,则返回的 Promise 也以相同的值解决;如果第一个 Promise 拒绝,则返回的 Promise 也以相同的拒绝原因被拒绝。

下面是一个简化的 myPromiseRace 函数,它模拟了 Promise.race 的行为:

function myPromiseRace(promises) {  
    return new Promise((resolve, reject) => {  
        // 遍历promises数组,为每个Promise添加.then()和.catch()处理器  
        promises.forEach(promise => {  
            promise.then(value => {  
                // 如果当前Promise解决,则立即解决返回的Promise  
                resolve(value);  
                // 注意:一旦resolve或reject被调用,Promise的状态就变为final,后续的.then或.catch不会被执行  
            }).catch(reason => {  
                // 如果当前Promise拒绝,则立即拒绝返回的Promise  
                reject(reason);  
            });  
              
            // 为了防止多个Promise同时解决或拒绝时导致多次调用resolve或reject,  
            // 我们不需要额外的逻辑来阻止这种情况,因为Promise规范保证了resolve和reject只会被调用一次。  
        });  
    });  
}  
  
// 使用myPromiseRace的示例  
const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'one'));  
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'two'));  
  
myPromiseRace([promise1, promise2]).then(value => {  
    console.log(value); // 不会执行,因为promise2更快地被拒绝了  
}).catch(reason => {  
    console.log(reason); // 输出: two  
});  
  
// 另一个示例,其中promise1更快地解决  
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'three'));  
const promise4 = new Promise((resolve) => setTimeout(resolve, 200, 'four'));  
  
myPromiseRace([promise3, promise4]).then(value => {  
    console.log(value); // 输出: three  
}).catch(reason => {  
    // 不会执行,因为所有Promise都解决了  
});

在这个实现中,我们为输入的每个 Promise 对象添加了 .then() 和 .catch() 处理器。由于 Promise 的规范保证了 resolve 和 reject 函数只会被调用一次,并且一旦 Promise 的状态变为 final(即已解决或已拒绝),后续的 .then() 或 .catch() 回调将不会被执行,因此我们不需要额外的逻辑来防止多次调用 resolve 或 reject

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2214178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面试-2024年7月16号

面试-2024年7月16号 自我介绍Mysql主从复制是做了一个什么样的集群?在Mysql的使用过程中遇到过哪些问题?mysql迁移具体步骤mysql漏洞修复是怎么做的。mysql的容灾方案(灾备恢复机制)。redis多节点怎么部署的redis的备份与恢复、迁…

电源中的“冷地”和“热地”

最近硬件同事在弄开关电源相关项目,由于其第一次做开关电源,并不懂冷地和热地的区别,出现示波器探头接地夹夹“热地”导致实验室多次跳闸,最严重时把板子给炸了。为了了解冷地和热地的如何辨别以及为什么热地带电这些知识&#xf…

【从零开发Mybatis】引入XNode和XPathParser

引言 在上文,我们发现直接使用 DOM库去解析XML 配置文件,非常复杂,也很不方便,需要编写大量的重复代码来处理 XML 文件的读取和解析,代码可读性以及可维护性相当差,使用起来非常不灵活。 因此&#xff0c…

JavaEE 多线程第二节 (多线程的简单实现Thread/Runable)

1. 创建线程(继承 Thread 类)步骤: 继承 Thread 类: 创建一个类并继承 Thread 类,然后重写 run() 方法,在该方法中写入线程执行的代码 class MyThread extends Thread {Overridepublic void run()…

数据恢复超简单!9 个方法任你选!小白也能轻易恢复数据!

在当今数字化的世界中,数据恢复的重要性日益凸显。无论是工作中的重要文档,还是生活中的珍贵照片和视频,一旦丢失,都可能给我们带来极大的困扰。别担心,下面为大家介绍 9 个超简单的数据恢复方法,让小白也能…

C++基础面试题 | 什么是C++中的运算符重载?

文章目录 回答重点:示例: 运算符重载的基本规则和注意事项: 回答重点: C的运算符重载是指可以为自定义类型(如类或结构体)定义运算符的行为,使其像内置类型一样使用运算符。通过重载运算符&…

它思科技CTO聂玮奇:消除“AI幻觉”,搭建高可靠对话云平台丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 近年来,大模型技术在全球范围内引起了广泛关注和应用热潮。 提到人工智能,很多人会想到它强大的运算能力和广泛的应用场景。如今,语言模型的发展如火如荼,但其中的“幻觉”问题却带…

基于SSM社区医院预约转诊管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档(1万字以上)开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统:Window操作系统 2、开发工具:IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

SwiftUI 6.0(iOS 18)自定义容器值(Container Values)让容器布局渐入佳境(上)

概述 我们在之前多篇博文中已经介绍过 SwiftUI 6.0(iOS 18)新增的自定义容器布局机制。现在,如何利用它们对容器内容进行“探囊取物”和“聚沙成塔”,我们已然胸有成竹了。 然而,除了上述鬼工雷斧般的新技巧之外&…

STM32_实验1_建立新工程

1、使用STM32CubeIDE建立一个新工程 1.1选择时钟源为外部晶振时钟。 1.2选择调试方式为 serial wire(串行线)。 1.3配置时钟树. 1.4选择以 c 和 h 文件型式管理工程文件。 1.5生成 hex 可执行文件。(完成后点击锤子) 2.串口输出调…

鸿蒙进入“无人区”:该如何闯关?

按照华为方面的说法,“打造鸿蒙操作系统是三大战役,目前已经完成了底座和体验两大战役,第三大战役则是生态。”生态固然重要,但要让鸿蒙与当今世界主流操作系统抗衡,乃至成为新一代操作系统中的翘楚,其实还…

每个程序员都应该了解的硬件知识

作者:shizhaoyang 在追求高效代码的路上,我们不可避免地会遇到代码的性能瓶颈。为了了解、解释一段代码为什么低效,并尝试改进低效的代码,我们总是要了解硬件的工作原理。于是,我们可能会尝试搜索有关某个架构的介绍、一些优化指南或者阅读一些计算机科学的教科书(如:计…

卡码网KamaCoder 94. 城市间货物运输 I

题目来源:94. 城市间货物运输 I C题解1(来源代码随想录):Bellman_ford 本题是经典的带负权值的单源最短路问题,此时就轮到Bellman_ford登场了。Bellman_ford算法的核心思想是 对所有边进行松弛n-1次操作(…

【 ACM独立出版】第二届通信网络与机器学习国际学术会议(CNML 2024,10月25-27)

官方信息 会议官网:www.cn-ml.org The 2nd International Conference on Communication Networks and Machine Learningwww.cn-ml.org 时间地点:2024年10月25-27日 | 中国-河南-郑州 截稿时间:2024年10日19日 (多轮截稿&#x…

51单片机的晾衣架控制系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块温湿度传感器光照传感器步进电机按键、LED、蜂鸣器等模块构成。适用于智能晾衣架等相似项目。 可实现功能: 1、LCD1602实时显示温湿度、光照强度和手动/自动信息 2、温湿度传感器DHT11采集温湿度信息 3、光照传感…

【数据结构与算法初阶】顺序表(上)

什么语言实现不重要,理解了思路就行,本篇使用C语言实现 一.顺序表含义(重要) 首先,顺序表属于线性表中的一中,线性表可以用多种方式实现,顺序表只是其中的一种 --------- 线性表是啥呢,通俗的说&#xff0…

lego-loam imageProjection.cpp源码注释(一)

一、主函数 int main(int argc, char** argv){ros::init(argc, argv, "lego_loam");ImageProjection IP;ROS_INFO("\033[1;32m---->\033[0m Image Projection Started.");ros::spin();return 0; }主函数很简单,常规ros初始化ros::init&…

程序员35岁丢了工作,应该怎么活?

35岁对很多程序员来说是个敏感的年龄段。在这个阶段,许多程序员已经有了丰富的工作经验和较高的薪水,但同时也面临着职场上不可忽视的年龄压力。尤其在一些技术密集型的公司,35岁之后的程序员可能被认为“年纪大了”,不再是招聘市…

【C语言】动态内存管理及相关笔试题

文章目录 一、为什么有动态内存分配二、malloc和free1.malloc函数的使用2.free函数的使用 三、calloc和realloc1.calloc函数的使用2.realloc函数的使用 四、常见动态内存分配的错误五、动态内存经典笔试题题1题2题3 六、总结C/C中程序内存区域划分 一、为什么有动态内存分配 我…

Struct Streaming

spark进行实时数据流计算时有两个工具 Spark Streaming:编写rdd代码处理数据流,可以解决非结构化的流式数据 Structured Streaming:编写df代码处理数据流,可以解决结构化和半结构化的流式数据 实时计算 实时计算,通常也称为“实时流计算”、“流式计算” 流数据处…