ES6异步编程中Promise与Proxy对象

Promise 对象

Promise对象用于解决Javascript中的地狱回调问题,有效的减少了程序回调的嵌套调用。

创建

如果要创建一个Promise对象,最简单的方法就是直接new一个。但是,如果深入学习,会发现使用Promise下的静态方法Promise.resolve()也能创建一个Promise对象:

// 创建方法一
new Promise((resolve, reject) => {// 此处做一个异步的事情
});// 创建方法二
Promise.resolve(p)	// p 可以是一个Promise,也可以是一个普通的数值。

使用方法二创建Promise时,可以传入一个普通的值,或一个Promise对象。最后都会作为一个Promise返回出来。如果传入的是一个普通的值,产生的Promise的值就会将这个值传入resolve方法发送给下一个then

使用

对于Promise对象的使用,参考下方的案例,对于Promise的使用,理解返回值、参数、两个回调之间的关系后会有一定的帮助。

第二种写法的区别主要在于直接在第一次定义Promise的同时把下一次then中的回调也顺便地写好了。

// 案例一
const n = 6
const p = new Promise((resolve, reject) => {setTimeout(() => {if (n > 5) {resolve(n)} else {reject('必须大于 5!')}}, 1000)
})
p.then((v) => {console.log(v)},(e) => {console.log(e)}
)
// 案例二
const pFn = function() {return Promise.resolve('解决!').then(v => {console.log('接收到', v);})
}
const p = pFn()

Promise.all() 方法

该方法用于一次性执行全部传入的[p1, p2, p3]对象,当全部执行成功后才会进入到第一个执行成功的then方法中。其中,任何一个失败了则会进入到then的失败回调中。

// 语法演示的伪代码
Promise.all([p1, p2, p3]).then((v) => {// 所有请求成功后的操作步骤},(e) => {// 某一个请求失败后的操作步骤}
)// 演示案例
function p(n) {return new Promise((resolve, reject) => {setTimeout(() => {if (n > 0) {resolve(n)} else {reject('不能小于 0!')}}, 1000)})
}
Promise.all([p(5), p(6), p(7)]).then((v) => {console.log(v)},(e) => {console.log(e)}
)

Promise.race() 方法

如果race的字面意思竞赛,该方法也是传入一个Promise对象的数组,不同点在于:先成功的Promise将直接进入到then的成功回调中。如果失败了,也直接进入到失败的then回调。

function loadData() {return new Promise((resolve, reject) => {setTimeout(() => {resolve('请求成功')}, 3000)})
}
function timeOut() {return new Promise((resolve, reject) => {setTimeout(() => {reject('请求超时')}, 5000)})
}
Promise.race([loadData(), timeOut()]).then((v) => {console.log(v)},(e) => {console.log(e)}
)

async 和 await 关键字

这两个关键字是Promise方法的语法糖,底层的实现还是Promise对象的那一套。优点在于能使异步编程的可读性进一步加强,使其更接近于同步执行的语法。

  • async 关键字
// async 语法糖的写法
async function fn() {return '12345'
}
fn().then((v) => {console.log(v)
})
// 等同于下方的写法
function fn() {return Promise.resolve('12345')}fn().then((v) => {console.log(v)})
  • await 关键字

这个关键字必须在async函数中使用。用于“等待” await后的表达式执行,并接受该表达式的返回值。

// 函数 p() 返回的是一个 Promise 对象,
// 延时 1 秒后执行成功回调函数,相当于模拟一次异步请求
function p(msg) {return new Promise((resolve, reject) => {setTimeout(() => {// 将函数 p() 的实参值 msg 作为执行成功回调函数的返回值resolve(msg)}, 1000)})
}// 一个用于正常输出内容的函数
function log() {console.log('2. 正在操作')
}async function fn() {console.log('1. 开始')await log()let p1 = await p('3. 异步请求')console.log(p1)console.log('4. 结束')
}
fn()

最后的执行顺序参考下图:

图片描述

Proxy 代理

通过Proxy代理可以为对象拦截一些特定的操作,proxy对象对于原对象的操作最终会转发给原对象,并且proxy对于原对象的值都只是引用的。

创建

// 伪代码
const proxy = new Proxy(target, handler)// 实际例子
const target = {}
const proxy = new Proxy(target, {})proxy.name = '闷墩儿'
console.log(proxy.name)
console.log(target.name)target.name = '憨憨'
console.log(proxy.name)
console.log(target.name)

其中最常用的拦截方法:

拦截方法方法说明
get(target, propKey, receiver)拦截对象属性的读取。
set(target, propKey, value, receiver)拦截对象属性的设置。
has(target, propKey)拦截 propKey in proxy 的操作。
ownKeys(target)拦截 Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)for...in 循环,返回一个数组。

get 方法

通过在handler对象中 加入get方法来使用,该方法会在请求原对象(target)的某一键(propKey)的值时调用,并且原对象和键都会作为get的回调参数。

const dog = { name: '闷墩儿' }
const proxy = new Proxy(dog, {get(target, propKey) {// 遍历目标对象的属性键值if (propKey in target) {return target[propKey] // 返回相应的属性值} else {throw new ReferenceError(propKey + ' 属性不存在')}},
})
console.log('访问 dog 对象中的 name 属性值为:' + proxy.name)
console.log('访问不存在的 age 属性:' + proxy.age)

set 方法

set会在你想设置原对象(target)的某一键(propKey),并将该键对应的值设置成你传入的值(value)时调用。额外需要知道的是返回值为设置成功与否的boolean值。

const validator = {set(target, propKey, value) {if (propKey === 'age') {// 判断 age 属性值是否时数字if (!Number.isInteger(value)) {throw new TypeError('狗狗的年龄只能是整型哦!')}}target[propKey] = valuereturn true},
}const dog = new Proxy({}, validator)
dog.age = '22'

has 方法

该方法在使用in查询属性时调用,该方法可以解决继承时属性继承出现的问题:

场景一中:valueOf实际上是Object的属性,因为dog默认继承自Object所以该属性默认也是dog的属性。

// 场景一:解决的问题
const dog = { name: '闷墩儿' }
console.log('name' in dog)
console.log('valueOf' in dog)// 场景二:使用实例
const dog = { name: '闷墩儿', age: 2 }
const handler = {has(target, propKey) {if (propKey == 'age' && target[propKey] < 5) {console.log(`${target.name}的年龄小于 5 岁哦!`)return true}},
}
const proxy = new Proxy(dog, handler)console.log('age' in proxy)

ownKeys

在使用迭代方法例如for...in迭代对象的键时可以使用ownKeys拦截该迭代,并返回你想给的迭代数组。

注意,你给的数组中的元素如果不是原对象的属性,将不会被迭代。

let dog = { name: '闷墩儿', age: 2, food: '狗罐头' }
const proxy = new Proxy(dog, {ownKeys() {return ['name', 'color']},
})for (let key in proxy) {console.log(key) // 输出 name
}

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

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

相关文章

UE自动索敌插件Target System Component

https://www.fab.com/zh-cn/listings/9088334d-3bde-4e10-a937-baeb780f880f ​ 一个完全用 C 编写的 UE插件&#xff0c;添加了对简单相机锁定/瞄准系统的支持。它最初​​在蓝图中开发和测试&#xff0c;然后转换并重写为 C 模块和插件。 特征&#xff1a; 可通过一组可在…

中小企业MES系统概要设计

版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、系统架构设计 1.1 整体架构模式 采用分层微服务架构&#xff0c;实现模块解耦与灵活扩展&#xff0c;支持混合云部署&#xff1a; #mermaid-svg-drxS3XaKEg8H8rAJ {font-family:"trebuchet ms",verdana,ari…

STM32移植U8G2

STM32 移植 U8G2 u8g2 &#xff08;Universal 8bit Graphics Library version2 的缩写&#xff09;是用于嵌入式设备的单色图形库&#xff0c;可以在单色屏幕中绘制 GUI。u8g2 内部附带了例如 SSD13xx&#xff0c;ST7xx 等很多 OLED&#xff0c;LCD 驱动。内置多种不同大小和风…

Langchain,为何要名为langchian?

来听听 DeepSeek 怎么说 Human 2025-05-02T01:13:43.627Z langchain 是一个大语言模型开发框架。我的理解中&#xff0c;lang 是词根"语言"&#xff0c;chain是单词"链"&#xff0c;langchain 便是将语言模型和组件串联成链的框架。而 langchain 的图标是…

Windows下Python3脚本传到Linux下./example.py执行失败

1. 背景 大多数情况下通过pycharm编写Python代码&#xff0c;编写调试完&#xff0c;到Linux下发布执行。 以example.py脚本为例 #! /usr/bin/env python3 #! -*- encoding: utf-8 -*- def test(x,y): xint x yint y cxy return c if _name_"__main__": print(test(2…

当MCP撞进云宇宙:多芯片封装如何重构云计算的“芯“未来?

当MCP撞进云宇宙:多芯片封装如何重构云计算的"芯"未来? 2024年3月,AMD发布了震撼业界的MI300A/B芯片——这颗为AI计算而生的"超级芯片",首次在单封装内集成了13个计算芯片(包括3D V-Cache缓存、CDNA3 GPU和Zen4 CPU),用多芯片封装(Multi-Chip Pac…

用定时器做微妙延时注意事项

注意定时器来着APB1还是APB2&#xff0c;二者频率不一样&#xff0c;配置PSC要注意 &#xff08;1&#xff09;高级定时器timer1&#xff0c; timer8以及通用定时器timer9&#xff0c; timer10&#xff0c; timer11的时钟来源是APB2总线 &#xff08;2&#xff09;通用定时器ti…

三类思维坐标空间与时空序位信息处理架构

三类思维坐标空间与时空序位信息处理架构 一、静态信息元子与元组的数据结构设计 三维思维坐标空间定义 形象思维轴&#xff08;x&#xff09;&#xff1a;存储多媒体数据元子&#xff08;图像/音频/视频片段&#xff09; 元子结构&#xff1a;{ID, 数据块, 特征向量, 语义…

spring boot中@Validated

在 Spring Boot 中&#xff0c;Validated 是用于触发参数校验的注解&#xff0c;通常与 ​​JSR-303/JSR-380​​&#xff08;Bean Validation&#xff09;提供的校验注解一起使用。以下是常见的校验注解及其用法&#xff1a; ​1. 基本校验注解​​ 这些注解可以直接用于字段…

Hadoop 单机模式(Standalone Mode)部署与 WordCount 测试

通过本次实验&#xff0c;成功搭建了 Hadoop 单机环境并运行了基础 MapReduce 程序&#xff0c;为后续分布式计算学习奠定了基础。 掌握 Hadoop 单机模式的安装与配置方法。 熟悉 Hadoop 环境变量的配置及 Java 依赖管理。 使用 Hadoop 自带的 WordCount 示例程序进行简单的 …

历史数据分析——运输服务

运输服务板块简介: 运输服务板块主要是为货物与人员流动提供核心服务的企业的集合,涵盖铁路、公路、航空、海运、物流等细分领域。该板块具有强周期属性,与经济复苏、政策调控、供需关系密切关联,尤其是海运领域。有不少国内股市的铁路、公路等相关的上市公司同时属于红利…

openEuler 22.03 安装 Mysql 5.7,TAR离线安装

目录 一、检查系统是否安装其他版本Mariadb数据库二、环境检查2.1 必要环境检查2.2 在线安装&#xff08;有网络&#xff09;2.3 离线安装&#xff08;无网络&#xff09; 三、下载Mysql2.1 在线下载2.2 离线下载 四、安装Mysql五、配置Mysql六、开放防火墙端口七、数据备份八、…

喷泉码技术在现代物联网中的应用 设计

喷泉码技术在现代物联网中的应用 摘 要 喷泉码作为一种无速率编码技术,凭借其动态生成编码包的特性,在物联网通信中展现出独特的优势。其核心思想在于接收端只需接收到足够数量的任意编码包即可恢复原始数据,这种特性使其特别适用于动态信道和多用户场景。喷泉码的实现主要…

GZIPInputStream 类详解

GZIPInputStream 类详解 GZIPInputStream 是 Java 中用于解压缩 GZIP 格式数据的流类,属于 java.util.zip 包。它是 InflaterInputStream 的子类,专门处理 GZIP 压缩格式(.gz 文件)。 1. 核心功能 解压 GZIP 格式数据(RFC 1952 标准)自动处理 GZIP 头尾信息(校验和、时…

网络编程——TCP和UDP详细讲解

文章目录 TCP/UDP全面详解什么是TCP和UDP&#xff1f;TCP如何保证可靠性&#xff1f;1. 序列号&#xff08;Sequence Number&#xff09;2. 确认应答&#xff08;ACK&#xff09;3. 超时重传&#xff08;Timeout Retransmission&#xff09;4. 窗口控制&#xff08;Sliding Win…

性能测试工具篇

文章目录 目录1. JMeter介绍1.1 安装JMeter1.2 打开JMeter1.3 JMeter基础配置1.4 JMeter基本使用流程1.5 JMeter元件作用域和执行顺序 2. 重点组件2.1 线程组2.2 HTTP取样器2.3 查看结果树2.4 HTTP请求默认值2.5 JSON提取器2.6 用户定义的变量2.7 JSON断言2.8 同步定时器&#…

rabbitMQ如何确保消息不会丢失

rabbitmq消息丢失的三种情况 生产者将消息发送到RabbitMQ的过程中时&#xff0c;消息丢失。消息发送到RabbitMQ&#xff0c;还未被持久化就丢失了数据。消费者接收到消息&#xff0c;还未处理&#xff0c;比如服务宕机导致消息丢失。 解决方案 生产者发送过程中&#xff0c;…

Beetle-RP2350 扩展板设计

Beetle-RP2350 扩展板设计 本文介绍了 DFRobot Beetle RP2350 开发板的扩展板设计&#xff0c;包括参数特点、效果展示、原理图、实物验证、工程测试等&#xff0c;为 RP2350 系列产品的开发提供了便捷。 PCB 工程详见&#xff1a;Beetle-RP2350扩展板 - 立创开源硬件平台 . …

2025年一加7pro刷twpr / magisk / kali nethunter教程+资源下载+避坑指南

从二手市场500淘了一个一加7pro 12+256 ,根据网上教程刷机但很多坑,折腾一周后搞定,记录下给后人避坑 资源下载:链接:https://pan.quark.cn/s/c16b972509f2 提取码:mUW7 本文是主流程+避坑指南,没有基础的需要手把手教学的shell都不会的就别看了,直接放弃或者tb找人花钱…

java HashMap,高效 哈希

java HashMap 有独特的设计。 哈希表数组的每个位置是一个哈希桶&#xff0c;里面由链表或红黑树实现。&#xff08;> 8 或 < 6 的变化时&#xff0c;避免频繁切换&#xff09; 容量&#xff08;capacity&#xff09;&#xff1a; 哈希表中桶&#xff08;bucket&#xf…