手写promise、call、apply、debounce、throttle 等

1、promise

     1.1  实现resolve和reject
class MyPromise {// 构造方法constructor(executor) {// 初始化值this.initValue()// 初始化this指向this.initBind()try {// 执行传进来的函数executor(this.resolve, this.reject)} catch (e) {// 捕捉到错误直接执行rejectthis.reject(e)}}initBind() {// 初始化thisthis.resolve = this.resolve.bind(this)this.reject = this.reject.bind(this)}initValue() {// 初始化值this.PromiseResult = null // 终值this.PromiseState = 'pending' // 状态}resolve(value) {// state是不可变的if (this.PromiseState !== 'pending') return// 如果执行resolve,状态变为fulfilledthis.PromiseState = 'fulfilled'// 终值为传进来的值this.PromiseResult = value}reject(reason) {// state是不可变的if (this.PromiseState !== 'pending') return// 如果执行reject,状态变为rejectedthis.PromiseState = 'rejected'// 终值为传进来的reasonthis.PromiseResult = reason}
}

测试代码:

const test3 = new MyPromise((resolve, reject) => {throw('fail')
})
console.log(test3) // MyPromise { PromiseState: 'rejected', PromiseResult: 'fail' }

 

  1.2  实现then方法
    then(onFulfilled, onRejected) {// 接收两个回调 onFulfilled, onRejected// 参数校验,确保一定是函数onFulfilled = typeof onFulfilled === 'function' ?onFulfilled : val => valonRejected = typeof onRejected === 'function' ?onRejected : reason => { throw reason }if (this.PromiseState === 'fulfilled') {// 如果当前为成功状态,执行第一个回调onFulfilled(this.PromiseResult)} else if (this.PromiseState === 'rejected') {// 如果当前为失败状态,执行第二哥回调onRejected(this.PromiseResult)}}

 测试代码:

// 输出 ”success“
const test = new MyPromise((resolve, reject) => {resolve('success')
}).then(res => console.log(res), err => console.log(err))

 

2、call

  2.1  实现思路

call() :在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。

 

let foo = {value: 1
};function bar() {console.log(this.value);
}bar.call(foo); // 1上述调用注意两点:
1. call 改变了 this 的指向,指向到 foo;
2. bar 函数执行了;上述方式等同于:
let foo = {value: 1,bar: function() {console.log(this.value)}
};foo.bar(); // 1

这个时候 this 就指向了 foo,但是这样却给 foo 对象本身添加了一个属性,所以们用 delete 再删除它即可。

所以我们模拟的步骤可以分为:

  1. 将函数设为对象的属性;

  2. 执行该函数;

  3. 删除该函数;

// 第一步
// fn 是对象的属性名,反正最后也要删除它,所以起什么都可以。
foo.fn = bar
// 第二步
foo.fn()
// 第三步
delete foo.fn
     2.2  实现

     2.2.1   指定this

     2.2.2   指定参数

     2.2.3   this 参数可以传 null,当为 null 的时候,视为指向 window

// 第三版
Function.prototype.call2 = function (context) {var context = context || window;context.fn = this;let arg = [...arguments].slice(1)let result = context.fn(...arg)delete context.fnreturn result
}// 测试一下
var value = 2;var obj = {value: 1
}function bar(name, age) {console.log(this.value);return {value: this.value,name: name,age: age}
}bar.call2(null); // 2console.log(bar.call2(obj, 'kevin', 18));
// 1
// Object {
//    value: 1,
//    name: 'kevin',
//    age: 18
// }

3、apply

      apply 的实现跟 call 类似,只是入参不一样,apply为数组

Function.prototype.apply = function (context, arr) {var context = Object(context) || window;context.fn = this;var result;if (!arr) {result = context.fn();}else {result = context.fn(...arr)}delete context.fnreturn result;
}

4、bind

5、debounce > 防抖

防抖: 如果在一定的时间内 (n) 频繁的触发,只会执行最后一次

      5.1  js实现
function debounce(func, ms) {let timeout;return function () {let context = this;let args = arguments;if (timeout) clearTimeout(timeout);timeout = setTimeout(() => {func.apply(context, args)}, ms);}
}
     5.1  hooks实现
import { useEffect, useRef } from 'react'const useDebounce = (fn, ms = 30, deps = []) => {let timeout = useRef()useEffect(() => {if (timeout.current) clearTimeout(timeout.current)timeout.current = setTimeout(() => {fn()}, ms)}, deps)const cancel = () => {  // 防止内存泄露clearTimeout(timeout.current)timeout = null}return [cancel]}export default useDebounce// 实际使用
import { useDebounce } from 'hooks'
const Home = (props) => {const [a, setA] = useState(0)const [b, setB] = useState(0)const [cancel] = useDebounce(() => {setB(a)}, 2000, [a])const changeIpt = (e) => {setA(e.target.value)}return <div><input type="text" onChange={changeIpt} />{ b } { a }</div>
}

6、throttle  > 节流

节流:每一次触发的时候,会记录与首次触发的一个时间差,如果时间差大于传入的这个时间,则重新计时

      6.1  js实现
function throttle(func, ms) {let previous = 0;return function() {let now = Date.now();let context = this;let args = arguments;if (now - previous > ms) {func.apply(context, args);previous = now;}}
}
      6.2  hooks实现
mport { useEffect, useRef, useState } from 'react'const useThrottle = (fn, ms = 30, deps = []) => {let previous = useRef(0)let [time, setTime] = useState(ms)useEffect(() => {let now = Date.now();if (now - previous.current > time) {fn();previous.current = now;}}, deps)const cancel = () => {setTime(0)}return [cancel]}export default useThrottle

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

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

相关文章

高铁Wifi是如何接入的?

使用PC端的朋友&#xff0c;请将页面缩小到最小比例&#xff0c;阅读最佳&#xff01; 在飞驰的高铁上&#xff0c;除了窗外一闪而过的风景&#xff0c;你是否好奇过&#xff0c;高铁Wifi信号如何连接的呢&#xff1f; 远动的火车可不能连接光纤吧&#xff0c;难道是连接的卫星…

CSS Canvas鼠标点击特效之天女散花(文本粒子动画)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><style>body,html {margin: 0;padding: 0;w…

工控一体机10.1寸显示器电容触摸屏(YA1308101JK)产品规格说明书

如果您对工控一体机有任何疑问或需求&#xff0c;或者对如何集成工控一体机到您的业务感兴趣&#xff0c;可移步控芯捷科技。 一、硬件功能介绍 YA1308101JK产品介绍&#xff1a; YA1308101JK搭载 Android10 主流操作系统&#xff0c;具有系统版本更高、占用内存更低、运行效率…

【领导力SE模型影响地图】如何分辨一个管理者有没有好的领导力? ​

影响地图是以思维导图的形式&#xff0c;在业务目标和交付物之间建立起强关联。 影响地图分为四个层级&#xff1a; 第1层级&#xff1a;目标&#xff08;Why&#xff09;- 想要达成的业务目标。 第2层级&#xff1a;利益相关者&#xff08;Who&#xff09;- 谁能够帮助达成…

新能源汽车推行精益生产:绿色动力下的效率革命

在新能源汽车行业迅猛发展的当下&#xff0c;推行精益生产已成为提升竞争力的关键所在。精益生产&#xff0c;作为一种以客户需求为导向、追求流程最优化和浪费最小化的管理理念&#xff0c;正逐步在新能源汽车领域展现出其独特的魅力。 新能源汽车的兴起&#xff0c;不仅代表了…

如何本地 Debug React 源码

日常开发过程中&#xff0c;有时 debug react 源代码进行问题排查。一种方案是直接把通过 html 引入进来&#xff0c;另外一种是编译并通过 yarn 链接到项目中&#xff0c;本地将介绍如何通过这两种方法进行代码 Debug。 页面引入源代码方式 这种方式比较简单&#xff0c;直接…

眼精星和金鸣识别新增智能结构化识别,助您快速筛选和统计数据

熟悉眼精星票证识别系统或金鸣表格文字识别大师的用户都知道&#xff0c;近日&#xff0c;这二款软件同时上线了“智能结构化”功能&#xff0c;那么&#xff0c;什么是智能结构化呢&#xff1f; 准确地说&#xff0c;我们这里的智能结构化应为OCR智能结构化&#xff0c;因为它…

多家大模型公司被爆“卖身”,有创业者称接单能力很重要

百模大战下&#xff0c;行业开始“洗牌”。 据外媒《The Information》的报道&#xff0c;随着底层通用大模型格局的基本落成&#xff0c;投资者的热情正在转向支持人形机器人等其他技术。 与此同时&#xff0c;科技巨头和生成式AI的早期赢家也正在加速掀起一场新浪潮&#x…

Flink搭建

目录 一、standalone模式 二、Flink on Yarn模式 一、standalone模式 解压安装Flink [rootbigdata1 software]# tar -zxvf flink-1.14.0-bin-scala_2.12.tgz -C /opt/module/ [rootbigdata1 module]# mv flink-1.14.0/ flink-standalone 2.进入conf修改flink-conf.yaml job…

KaiwuDB 受邀出席中国智能化油气管道与智慧管网技术交流大会

导 读 5月22-24日&#xff0c;由中国石油学会石油储运专业委员会、石油工业标准化技术委员会油气储运专标委等联合主办的“第十三届中国智能化油气管道与智慧管网技术交流大会”在浙江省杭州市盛大召开&#xff0c;KaiwuDB 受邀亮相大会。浪潮院士、山东浪潮数据库技术有限公司…

二区5分纯生信|单细胞+非负矩阵+AlphaFold+机器学习组合

说在前面 学文不看刊 这篇分析总体来说工作量不算大&#xff0c;scRNA联合bulkRNA分析&#xff0c;多种机器学习组合预测模型&#xff0c;最后用了AlphaFold2预测蛋白及AutoDock分子对接 非常适合小白学习和模仿&#xff0c;其次在筛选出核心基因后可以再加几个外部数据集观…

勒索软件统计数据揭示了网络勒索的惊人速度

本文通过各种报告摘录&#xff0c;提供了有关当前勒索软件形势的统计数据和见解。 全球勒索病毒危机加剧 NTT安全控股《2024全球威胁情报报告》&#xff08;2024年5月&#xff09; 据NTT安全控股公司的《2024年全球威胁情报报告》显示&#xff0c;勒索软件和勒索事件在2023年激…

50 http通用服务器

虽然我们说&#xff0c;应用层协议是我们程序猿自己定的 但实际上&#xff0c;已经有大佬们定义了一些现成的&#xff0c;又非常好用的应用层协议&#xff0c;供我们直接参考使用&#xff0c;http&#xff08;超文本传输协议&#xff09;就是其中之一 目录 认识urlurlencode和…

为WPF的Grid添加网格边框线

在WPF中使用Grid绘制表格的时候&#xff0c;如果元素较多、排列复杂的话&#xff0c;界面会看起来很糟糕&#xff0c;没有层次&#xff0c;这时用网格或边框线分割各元素&#xff08;标签或单元格&#xff09;将会是页面看起来整齐有条理。 默认没有边框线的如下图所示&#xf…

二叉树习题精讲-相同的树

相同的树 100. 相同的树 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/same-tree/description/ /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ bool i…

考研经验总结——复试上岸(附通信原理)

上岸啦&#xff0c;一志愿拟录取&#xff0c;初试第5、复试4&#xff0c;总成绩第4 文章目录 一、复试流程二、注意事项三、简历模板3.1 基本信息3.2 报考情况3.3 校内实践3.4 荣誉奖励3.5 项目经验3.6 自我介绍 四、通信原理五、最后的总结 一、复试流程 1、 复试流程 准备复…

基于Netty实现WebSocket服务端

本文基于Netty实现WebSocket服务端&#xff0c;实现和客户端的交互通信&#xff0c;客户端基于JavaScript实现。 在【WebSocket简介-CSDN博客】中&#xff0c;我们知道WebSocket是基于Http协议的升级&#xff0c;而Netty提供了Http和WebSocket Frame的编解码器和Handler&#…

N1912A P 系列双通道功率计

N1912A 双通道功率计 产品综述 <<<P 系列双通道功率计>>> Keysight N1912A P 系列双通道功率计可以提供峰值功率、峰均比、平均功率、上升时间、下降时间 NS 脉冲宽度测量。 “ 功能特点 30 MHz 视频带宽 能够以高达 100 MSa/s 的采样率执行单次实时捕…

2种方法将集合数据List构建成树形结构

文章目录 递归循环构建树结构hutool.TreeUtil.build构建树结构 递归循环构建树结构 先查最外层树节点数据&#xff0c;再递归遍历每一层子节点数据 public ApiResultDto<List<LocationDto>> getTreeByParams(LocationSearchDto searchDto, SecurityUser user) {// …

柔性自驱动生物“电子衣”促进伤口愈合

引用信息 文 章&#xff1a;Combined Amniotic Membrane and Self-Powered Electrical Stimulator Bioelectronic Dress Promotes Wound Healing 期 刊&#xff1a;ACS Applied Materials & Interfaces&#xff08;影响因子&#xff1a;9.5&#xff09; 发表时间…