自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ECMAScript新提案:AsyncContext.Variable 和 AsyncContext.Snapshot

開發(fā) 后端
異步編程使 JavaScript 能夠以非阻塞的方式執(zhí)行任務(wù),這意味著它不必等待一個(gè)操作完成,然后再繼續(xù)下一個(gè)操作。它是一個(gè)功能強(qiáng)大的工具,但也可能導(dǎo)致棘手的問題,尤其是在管理異步調(diào)用之間的上下文時(shí)。

JavaScript 已成為編程中最通用和使用最廣泛的語(yǔ)言之一。無論您是在開發(fā)一個(gè)活潑的交互式網(wǎng)頁(yè),還是為您的 Web 應(yīng)用程序制作一個(gè)強(qiáng)大、可擴(kuò)展的后端,JavaScript 都有您需要的工具和庫(kù)。但是,像所有語(yǔ)言一樣,它當(dāng)然有其局限性和挑戰(zhàn)。其中一個(gè)挑戰(zhàn)是處理異步操作,這是編程的一個(gè)重要方面。

異步編程使 JavaScript 能夠以非阻塞的方式執(zhí)行任務(wù),這意味著它不必等待一個(gè)操作完成,然后再繼續(xù)下一個(gè)操作。它是一個(gè)功能強(qiáng)大的工具,但也可能導(dǎo)致棘手的問題,尤其是在管理異步調(diào)用之間的上下文時(shí)。

這個(gè)問題是新的異步上下文提案可以進(jìn)行解決。本文提供了一個(gè)全面的指南,用于理解異步上下文提案,它對(duì)服務(wù)器端JavaScript的影響,以及它對(duì)JavaScript開發(fā)的未來可能意味著什么。

如果你熟悉異步 JavaScript 的歷史,我建議直接跳到什么是異步上下文 API?從這篇文章中獲得最大收益。

了解異步 JavaScript 代碼

在我們深入研究異步上下文提案之前,讓我們確保我們對(duì)異步代碼的含義達(dá)成共識(shí)。

簡(jiǎn)單來說,異步編程是一種設(shè)計(jì)模式,它允許程序在等待操作完成的同時(shí)繼續(xù)執(zhí)行其他任務(wù)。這種設(shè)計(jì)模式與同步編程形成鮮明對(duì)比,在同步編程中,程序按順序執(zhí)行每個(gè)任務(wù),并且僅在當(dāng)前任務(wù)完成后才繼續(xù)執(zhí)行下一個(gè)任務(wù)。

JavaScript是一種單線程語(yǔ)言,這意味著它一次只能做一件事。但是,它需要處理許多操作,如網(wǎng)絡(luò)請(qǐng)求、計(jì)時(shí)器等,這些操作不能完全適應(yīng)單線程任務(wù)隊(duì)列。這就是事件循環(huán)的用武之地。

事件循環(huán)

事件循環(huán)是 JavaScript 環(huán)境中支持異步 JavaScript 的重要組成部分。它不斷循環(huán)遍歷調(diào)用堆棧并檢查要執(zhí)行的任務(wù)。

假設(shè)一個(gè)任務(wù)還沒有準(zhǔn)備好執(zhí)行,例如當(dāng)它正在等待來自服務(wù)器的數(shù)據(jù)時(shí)——事件循環(huán)可以移動(dòng)到下一個(gè)任務(wù),并在準(zhǔn)備好后返回到等待任務(wù)。這樣,JavaScript 可以隨著時(shí)間的推移處理多個(gè)任務(wù),而不會(huì)停止或阻止程序的其余部分。

JavaScript 提供了幾種編寫異步代碼的技術(shù)。早期版本的 JavaScript 依賴于回調(diào),其中一個(gè)函數(shù)將傳遞到另一個(gè)函數(shù)并在以后運(yùn)行。然而,這種方法導(dǎo)致了臭名昭著的“回調(diào)地獄”,這是一種深度嵌套回調(diào)的情況,使代碼難以閱讀和維護(hù)。

JavaScript的Promise和 async/await

為了解決這個(gè)問題,JavaScript 引入了 Promise,它表示異步操作的最終結(jié)果(成功或失?。┘捌浣Y(jié)果值。Promise有助于扁平化嵌套回調(diào),并使異步代碼更易于使用。

他們還支持使用 async/await 語(yǔ)法,進(jìn)一步提高了異步 JavaScript 代碼的可讀性。通過 async/await,開發(fā)人員可以編寫讀起來與同步代碼非常相似的異步代碼,從而更輕松地理解數(shù)據(jù)流和事件。

然而,雖然這些工具使異步JavaScript更易于管理,但它們?nèi)匀淮嬖谝恍﹩栴}。主要問題之一是通過事件循環(huán)傳遞代碼時(shí)隱式上下文丟失。讓我們?cè)谙乱还?jié)中深入研究這一挑戰(zhàn)。

異步上下文的挑戰(zhàn)

正如我們所提到的,JavaScript的事件循環(huán) - 結(jié)合Promise和async/await - 允許開發(fā)人員編寫異步代碼,比嵌套回調(diào)更容易管理和理解。但是,這些工具存在自己的困難:通過事件循環(huán)傳遞代碼時(shí),來自調(diào)用站點(diǎn)的某些隱式信息會(huì)丟失。

這個(gè)“隱含信息”是什么?在同步代碼執(zhí)行中,值在執(zhí)行的生命周期內(nèi)始終可用。它們可以顯式傳遞,如函數(shù)參數(shù)或封閉變量(在外部作用域中定義,但由內(nèi)部函數(shù)引用),也可以隱式傳遞,例如存儲(chǔ)在多個(gè)作用域可訪問的變量中的值。

但是,當(dāng)涉及到異步執(zhí)行時(shí),情況會(huì)發(fā)生變化。讓我們用一個(gè)例子來說明這一點(diǎn)。假設(shè)您有一個(gè)在不同函數(shù)作用域之間共享的變量,并且其值在異步函數(shù)執(zhí)行期間發(fā)生變化。

在函數(shù)執(zhí)行開始時(shí),共享變量可能具有一定的值。但是,當(dāng)函數(shù)完成時(shí)(例如, await 在操作之后),該共享變量的值可能已更改,從而導(dǎo)致潛在的意外結(jié)果。

這就是在異步 JavaScript 中丟失隱式調(diào)用站點(diǎn)信息的問題出現(xiàn)的地方。無論您使用的是Promise鏈還是async/await,事件循環(huán)的行為都保持不變。

但是,當(dāng)事件循環(huán)執(zhí)行異步代碼時(shí),調(diào)用堆棧(跟蹤函數(shù)調(diào)用以及函數(shù)調(diào)用后返回位置的機(jī)制)會(huì)被修改。這意味著在原始調(diào)用站點(diǎn)上隱式提供的信息可能會(huì)在異步函數(shù)完成時(shí)丟失。

async/await 語(yǔ)法的引入雖然總體上是一個(gè)積極的變化,但使這個(gè)問題進(jìn)一步復(fù)雜化。由于 async/await 使異步代碼看起來與同步代碼非常相似,因此更難看到調(diào)用堆棧和上下文被修改的位置。這可能會(huì)導(dǎo)致錯(cuò)誤和不可預(yù)測(cè)的行為,以及難以追蹤的意外錯(cuò)誤。

認(rèn)識(shí)到這個(gè)問題,TC39委員會(huì)成員Chengzhong Wu和Justin Ridgewell一直在尋求一種在異步操作中保留上下文的方法。他們的解決方案是異步上下文API。

什么是異步上下文 API?

異步上下文 API 是一種強(qiáng)大的新機(jī)制,用于處理異步上下文提案中提出的異步 JavaScript 代碼中的上下文。截至 2023 年 8 月,該提案目前處于 ECMAScript 標(biāo)準(zhǔn)化流程的第 2 階段,這意味著它已被批準(zhǔn)為提案草案,目前正在積極開發(fā)中。盡管該提案仍可能發(fā)生變化,但它被認(rèn)為是包含在下一版 JavaScript 中的可行候選者。

異步上下文 API 將允許 JavaScript 通過事件循環(huán)在轉(zhuǎn)換中捕獲和使用隱式調(diào)用站點(diǎn)信息。它允許開發(fā)人員編寫與同步代碼非常相似的異步代碼,即使在需要隱式信息的情況下也是如此。

此 API 圍繞兩個(gè)基本構(gòu)造展開: AsyncContext.Variable 和 AsyncContext.Snapshot 。這些構(gòu)造允許開發(fā)人員在異步代碼塊中創(chuàng)建、操作和檢索上下文變量,從而提供通過異步代碼(如 Promise 延續(xù)或異步回調(diào))傳播值的機(jī)制。

AsyncContext.Variable 類

該 AsyncContext.Variable 類允許您創(chuàng)建一個(gè)可以在異步上下文中設(shè)置和訪問的新變量。該方法 run 在函數(shù)執(zhí)行期間為變量設(shè)置值,而 get 該方法檢索變量的當(dāng)前值。

AsyncContext.Snapshot 類

另一方面,該 AsyncContext.Snapshot 類使您能夠捕獲給定 AsyncContext.Variable 時(shí)間所有實(shí)例的當(dāng)前值。這就像拍攝所有上下文變量狀態(tài)的“快照”,然后可以使用這些快照在以后使用這些捕獲的值執(zhí)行函數(shù)。

這些新結(jié)構(gòu)有望大大簡(jiǎn)化異步JavaScript中的上下文管理。借助異步上下文 API,開發(fā)人員可以保持一致對(duì)所需隱式信息的訪問,無論他們執(zhí)行多少異步操作。

使用 AsyncContext

讓我們看一下異步上下文提案 AsyncContext 中的命名空間聲明:

namespace AsyncContext {
  class Variable<T> {
    constructor(options: AsyncVariableOptions<T>);

    get name(): string;

    run<R>(value: T, fn: (...args: any[])=> R, ...args: any[]): R;

    get(): T | undefined;
  }

  interface AsyncVariableOptions<T> {
    name?: string;
    defaultValue?: T;
  }

  class Snapshot {
    constructor();

    run<R>(fn: (...args: any[]) => R, ...args: any[]): R;
  }
}

AsyncContext 命名空間引入了幾個(gè)基本類和一個(gè)接口:

  • Variable :此類表示可以保存值的上下文變量;泛型類型 <T> 指示變量可以保存任何數(shù)據(jù)類型。它還有一個(gè) run() 設(shè)置變量值并執(zhí)行函數(shù)的方法,其 get() 方法返回變量的當(dāng)前值
  • AsyncVariableOptions :這是一個(gè)接口,用于定義可以傳遞給構(gòu)造函數(shù)的 Variable 可能選項(xiàng)。它可以包含變量的名稱和默認(rèn)值
  • Snapshot :此類捕獲特定 AsyncContext.Variables 時(shí)刻的所有狀態(tài)。它有一個(gè) run() 方法,該方法使用拍攝快照時(shí)的變量值執(zhí)行函數(shù)

理解 AsyncContext.Variable

讓我們更深入地了解工作原理 AsyncContext.Variable 。假設(shè)您有一個(gè) asyncVar 的實(shí)例 AsyncContext.Variable 。若要在函數(shù)執(zhí)行期間設(shè)置 其 asyncVar 值,請(qǐng)使用 run 該方法。此方法將以下內(nèi)容作為其前兩個(gè)參數(shù):

  1. 要設(shè)置的值 asyncVar
  2. 其執(zhí)行 asyncVar 應(yīng)保存該值的函數(shù)

下面是一個(gè)示例:

const asyncVar = new AsyncContext.Variable()
asyncVar.run('top', main)

在此代碼中, asyncVar 在 main 函數(shù)執(zhí)行期間設(shè)置為字符串“top”。然后可以使用 在 main asyncVar.get() 函數(shù)中訪問此值。請(qǐng)注意,通過 AsyncContext API, AsyncContext.Variable 實(shí)例旨在跨同步和異步操作(例如使用 setTimeout 。

有趣的是, AsyncContext.Variable 運(yùn)行可以嵌套。這意味著您可以在已運(yùn)行的函數(shù) asyncVar 中調(diào)用該方法, run 并設(shè)定了 的值 asyncVar 為 。在這種情況下,在內(nèi)部函數(shù)執(zhí)行期間采用新值, asyncVar 然后在內(nèi)部函數(shù)完成后恢復(fù)為以前的值。

理解 AsyncContext.Snapshot

該 AsyncContext.Snapshot 類用于捕獲特定時(shí)間點(diǎn)所有 AsyncContext.Variable 實(shí)例的狀態(tài)。這是通過調(diào)用構(gòu)造函數(shù)來完成的 Snapshot ??煺丈院罂捎糜谶\(yùn)行函數(shù),就好像捕獲的值仍然是其各自變量的當(dāng)前值一樣。這是通過 Snapshot 實(shí)例的方法完成 run 的。

讓我們看一個(gè)例子:

asyncVar.run('top', () => {
  const snapshotDuringTop = new AsyncContext.Snapshot()

  asyncVar.run('C', () => {
    snapshotDuringTop.run(() => {
      console.log(asyncVar.get()) // => 'top'
    })
  })
})

在此代碼中, 生成 snapshotDuringTop 創(chuàng)建時(shí)所有 AsyncContext.Variable 實(shí)例狀態(tài)的快照。稍后,在asyncVar的方法中 run ,使用 run.snapshotDuringTop的asyncVar方法。

即使此時(shí)設(shè)置為“C”,在 asyncVar snapshotDuringTop.run() 執(zhí)行中,的值 asyncVar 仍然是“top”,因?yàn)檫@是創(chuàng)建時(shí) snapshotDuringTop 的值。

異步上下文 API 的影響

提議的Async Context API對(duì)于JavaScript開發(fā)人員具有巨大的潛力,特別是那些使用Node.js等服務(wù)器端JavaScript環(huán)境的開發(fā)人員。此 API 將使開發(fā)人員能夠更有效地處理異步代碼中的上下文,提供在執(zhí)行的特定點(diǎn)設(shè)置、檢索和“凍結(jié)”上下文的函數(shù)。

這可能會(huì)使開發(fā)人員擺脫在異步操作中管理上下文的復(fù)雜性,并大大增強(qiáng)可跟蹤性和調(diào)試,從而可以更好地專注于編寫有效和高效的代碼。

更實(shí)際地說,如果實(shí)現(xiàn),異步上下文可以顯著增強(qiáng)各種用例,例如:

  • 使用與異步調(diào)用堆棧相關(guān)的信息批注日志
  • 跨邏輯異步控制線程收集性能信息
  • 提供對(duì)應(yīng)用程序性能的準(zhǔn)確洞察

它還可以通過在整個(gè)請(qǐng)求處理過程中維護(hù)上下文來改進(jìn) Web API 的功能,例如優(yōu)先級(jí)任務(wù)計(jì)劃,甚至跨多個(gè)異步操作。

此外,異步上下文 API 可以幫助改進(jìn)錯(cuò)誤處理,使開發(fā)人員能夠更準(zhǔn)確地將異常跟蹤到其原始上下文,從而縮短解決時(shí)間。它還可以通過跨異步邊界管理和維護(hù)上下文來提供更有效的并發(fā)控制。

在更大的范圍內(nèi),Async Context提案代表了JavaScript持續(xù)發(fā)展的重要進(jìn)步,特別是對(duì)于異步編程。通過解決異步編程帶來的一些獨(dú)特挑戰(zhàn),它可以提供一個(gè)強(qiáng)大、靈活的解決方案。然而,該提案仍處于早期階段,其最終影響將取決于其在 JavaScript 社區(qū)中的最終實(shí)現(xiàn)和采用。

寫在最后

如果實(shí)現(xiàn),異步上下文 API 將為開發(fā)人員提供更強(qiáng)大的工具來管理異步代碼中的上下文。在異步環(huán)境中傳播上下文的能力可能是變革性的,從而帶來更準(zhǔn)確的跟蹤、調(diào)試和性能監(jiān)視。

JavaScript 的未來可能會(huì)繼續(xù)強(qiáng)調(diào)異步操作的有效處理,而像 Async Context 這樣的提案代表了邁向未來的必要步驟。

責(zé)任編輯:姜華 來源: 宇宙一碼平川
相關(guān)推薦

2021-12-27 07:59:50

ECMAScript JSON模塊Node.js

2023-02-03 17:16:33

ECMAScriptAPITC39

2023-01-05 08:00:24

RegExpFoo類字段

2021-08-09 10:36:20

GoSlices Maps

2022-01-11 12:13:33

JavaScript編程語(yǔ)言

2021-02-25 15:51:41

Go語(yǔ)言模糊測(cè)試功能

2023-06-28 00:40:01

ECMAScriptWeakMapSymbol

2022-06-24 08:33:13

ECMAScriptjavaScript

2021-07-27 13:08:52

微軟Chrome新提案

2023-12-27 08:03:53

Go優(yōu)化代碼

2024-06-28 11:39:21

2025-02-07 15:58:43

2022-06-08 10:46:00

CSS前端

2021-12-13 08:52:42

Go 泛型

2010-08-26 10:20:43

2022-11-15 09:16:59

2022-03-29 09:03:08

JavaScript數(shù)組語(yǔ)義

2024-11-19 09:10:19

迭代器Go語(yǔ)言

2023-07-17 10:21:25

TC39JavaScript

2025-03-10 08:10:00

安全賦值運(yùn)算符ECMAScript編碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)