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.pswp.cn/web/78133.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78133.shtml
英文地址,請注明出處:http://en.pswp.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…