成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Signals 在JavaScript中的應(yīng)用

開發(fā) 前端
自從聲明式JavaScript框架問世以來,Signals機(jī)制一直存在。隨著時(shí)間的推移,它采用了許多不同的名稱,經(jīng)歷了多年的流行和消失。

最近,"Signals"成為了前端備受關(guān)注的話題。很多國外的大佬都發(fā)文表示Signals是前端框架的未來。同時(shí),尤大也在Vue官網(wǎng)上添加了"Connection to Signals"部分。此外,包括Solid、Angular、Preact、Qwik和Vue等多個(gè)前端框架都已經(jīng)開始實(shí)現(xiàn)Signals。

作為一名FE,如果你和我之前一樣還不是很了解Signals,那么這篇文章或許可以幫助你更好地了解一下這個(gè)技術(shù)。本文將介紹Signals的歷史、概念和優(yōu)勢。

一、發(fā)展歷史

自從聲明式JavaScript框架問世以來,Signals機(jī)制一直存在。隨著時(shí)間的推移,它采用了許多不同的名稱,經(jīng)歷了多年的流行和消失。

在聲明式JavaScript框架中,組件是聲明其輸出的單元,可以被動(dòng)態(tài)地渲染和組合。這種方式的優(yōu)點(diǎn)是,它允許開發(fā)人員集中精力于組件的輸出,而無需擔(dān)心組件如何被渲染和更新。這種抽象方式也使得組件更容易被復(fù)用,并且更容易理解和測試。

然而,這種抽象也帶來了一些挑戰(zhàn)。其中一個(gè)挑戰(zhàn)是組件之間如何通信和共享狀態(tài)。這些問題可能導(dǎo)致代碼變得笨重,難以維護(hù),并且在復(fù)雜的應(yīng)用程序中容易出現(xiàn)混亂。因此,開發(fā)人員需要一種更靈活、更強(qiáng)大的通信機(jī)制來解決這些問題。

在這種情況下,Signals機(jī)制成為了一個(gè)有用的解決方案。Signals機(jī)制允許組件在不直接引用其他組件的情況下通信,并且能夠更靈活地傳遞消息和狀態(tài)。這些機(jī)制可以是事件、回調(diào)、Promise或其他異步機(jī)制。它們可以被用來處理各種不同的場景,例如用戶交互、網(wǎng)絡(luò)請求和狀態(tài)更改等。

Signals機(jī)制還具有許多其他優(yōu)點(diǎn)。它們可以提高應(yīng)用程序的可維護(hù)性和可擴(kuò)展性,并且可以幫助開發(fā)人員更好地理解和調(diào)試代碼。此外,由于Signals機(jī)制允許組件之間松散耦合,因此它們也有助于提高代碼的可重用性。

1.1 早期實(shí)現(xiàn)

有時(shí)令人驚訝的是,多個(gè)團(tuán)隊(duì)幾乎在同一時(shí)間達(dá)成了相似的解決方案。聲明式JavaScript框架的開端有三個(gè)版本:Knockout.js(2010年7月),Backbone.js(2010年10月)和Angular.js(2010年10月)。

Angular的臟檢查,Backbone的模型驅(qū)動(dòng)的重渲染,以及Knockout的細(xì)粒度更新。每一個(gè)都略有不同,但最終都將成為我們今天管理狀態(tài)和更新DOM的基礎(chǔ)。

1.2 數(shù)據(jù)綁定

Angular.js里面常用的模式叫作數(shù)據(jù)綁定。數(shù)據(jù)綁定是將部分狀態(tài)(state)附加到視圖樹(view tree)某個(gè)特定部分的一個(gè)方法。可以做到的一個(gè)強(qiáng)大的事情是使其成為雙向的。因此,我們可以讓狀態(tài)更新 DOM,反過來,DOM 事件自動(dòng)更新狀態(tài),所有這些都是以一種簡單的聲明方式進(jìn)行的。但是如果濫用也會(huì)出現(xiàn)問題,在 Angular 中,如果不知道有什么變化,就會(huì)對整個(gè)樹進(jìn)行骯臟的檢查,向上傳播可能會(huì)導(dǎo)致它發(fā)生多次。

1.3 Mobx

之后就是react的時(shí)代,react對狀態(tài)管理沒有太多的限制。MobX就是這種解決方案。它強(qiáng)調(diào)一致性和無障礙傳播。也就是說,對于任何給定的變化,系統(tǒng)的每一部分都只運(yùn)行一次,而且是以適當(dāng)?shù)捻樞蛲竭\(yùn)行。

它通過將先前方案中典型的基于 push 的響應(yīng)式換成 push-pull 混合系統(tǒng)來做到這一點(diǎn)。變化的通知被推送出去,但派生狀態(tài)的執(zhí)行被推遲到讀取它的地方。

圖片

1.4 Vue

Vue(2014) 也為今天的發(fā)展提供了巨大的貢獻(xiàn)。除了在優(yōu)化一致性方面與 MobX 保持一致外,Vue從一開始就將「細(xì)粒度」的響應(yīng)性作為其核心。

雖然 Vue 與 React 共享虛擬 DOM 的使用,但響應(yīng)性是一流的,這意味著它首先作為一種內(nèi)部機(jī)制與框架一起開發(fā),以支持其 Options API,并在過去幾年中,成為 Composition API 的核心 (2020)。

Vue 通過調(diào)度任務(wù),將 pull / push 機(jī)制向前推進(jìn)了一步。默認(rèn)情況下,Vue 的修改不會(huì)立馬被執(zhí)行,而是要等到下一個(gè)微任務(wù)才會(huì)執(zhí)行。

然而,這種調(diào)度也可以用來做一些其他的事情,比如 keep-alive,以及 Suspense。甚至像并發(fā)渲染這樣的事情也可以用這種方法來實(shí)現(xiàn),真正展示了如何獲得基于 pull 和 push 的兩種方法的最佳效果。

二、為什么是Signals

Signals 的獨(dú)特之處在于狀態(tài)更改會(huì)以最有效的方式來自動(dòng)更新組件和 UI。Signals 基于自動(dòng)狀態(tài)綁定和依賴跟蹤提供了出色的工效,并具有針對虛擬 DOM 優(yōu)化的獨(dú)特實(shí)現(xiàn)。

2.1 狀態(tài)管理的困境

隨著應(yīng)用越來越復(fù)雜,項(xiàng)目中的組件也會(huì)越來越多,需要管理的狀態(tài)也越來越多。

為了實(shí)現(xiàn)組件狀態(tài)共享,一般需要將狀態(tài)提升到組件的共同的祖先組件里面,通過 props 往下傳遞,帶來的問題就是更新時(shí)會(huì)導(dǎo)致所有子組件跟著更新,需要配合 memo 和 useMemo 來優(yōu)化性能。

雖然這聽起來還挺合理,但隨著項(xiàng)目代碼的增加,我們很難確定這些優(yōu)化應(yīng)該放到哪里。

即使添加了 memoization,也常常因?yàn)橐蕾囍挡环€(wěn)定變得無效,由于 Hooks 沒有可以用于分析的顯式依賴關(guān)系樹,所以也沒法使用工具來找到原因。

圖片

另一種解決方案就是放到 Context 上面,子組件作為消費(fèi)者自行通過 useContext 來獲取需要的狀態(tài)。

但是有一個(gè)問題,只有傳給 Provider 的值才能被更新,而且只能作為一個(gè)整體來更新,無法做到細(xì)粒度的更新。

為了處理這個(gè)問題,只能將 Context 進(jìn)行拆分,業(yè)務(wù)邏輯又不可避免地會(huì)依賴多個(gè) Context,這樣就會(huì)出現(xiàn) Context 套娃現(xiàn)象。

圖片

2.2 通向未來的 Signals

Signal 的核心是一個(gè)通過.value屬性 來保存值的對象。它有一個(gè)重要特征,那就是 Signal 對象的值可以改變,但 Signal 本身始終保持不變。

import { signal } from "@preact/signals";

const count = signal(0);

// Read a signal’s value by accessing .value:
console.log(count.value); // 0

// Update a signal’s value:
count.value += 1;

// The signal's value has changed:
console.log(count.value); // 1

在 Preact 中,當(dāng) Signal 作為 props 或 context 向下傳遞時(shí),傳遞的是對 Signal 的引用。這樣就可以在不重新渲染組件的情況下更新 Signal,因?yàn)閭鹘o組件的是 Signal 對象而不是它的值。

這讓我們可以跳過所有昂貴的渲染工作,立即跳到任意訪問 signal.value 屬性的組件。

圖片

Signals 具有第二個(gè)重要特征,即它們會(huì)跟蹤其值何時(shí)被訪問以及何時(shí)被更新。在 Preact 中,當(dāng) Signal 的值發(fā)生變化時(shí),從組件內(nèi)訪問 Signal 的屬性會(huì)自動(dòng)重新渲染組件。

通過Preact的使用,我們可以總結(jié)Signals 幾點(diǎn)特點(diǎn):1、感覺上像是使用原始數(shù)據(jù)結(jié)構(gòu) 2、能根據(jù)值的變化自動(dòng)更新 3、直接更新 DOM (換句話來說無 VDOM) 4、沒有依賴數(shù)組

三、在SolidJS中的使用

const Greeting = (props) => (
<>Hi <span>{props.name}</span></>
);

const App(() => {
const [visible, setVisible] = createSignal(false),
[name, setName] = createSignal("Josephine");

return (
<div notallow={() => setName("Geraldine")}>{
visible() && <Greeting name={ name } />
}</div>
);
});

render(App, document.body);

可以看到 SolidJS 響應(yīng)式也是Signal 作為基礎(chǔ),createSignal 既可以用于組件內(nèi),也可以用于組件外,這個(gè)跟 Preact 中類似。一方面可以將 Signal 作為組件的 local state,也可以定義為 global State。與前面類似,SolidJS 中也有以下相似點(diǎn):

  • 響應(yīng)式細(xì)粒度更新
  • 無需定義 dependencies
  • 惰性取值

SolidJS 與 Mobx 和 Vue 的響應(yīng)式非常相似,但是不會(huì)處理 VDOM,而是直接更新 DOM。

四、手動(dòng)實(shí)現(xiàn)一個(gè)

響應(yīng)式狀態(tài)管理三要素,Signals、Reactions、Derivations

// context 包含Reactions中的執(zhí)行方法和Signal依賴
const context = [];

const createSignal = (value) => {
const subscriptions = new Set();
const readFn = () => {
const running = context.pop();
if (running) {
subscriptions.add({
execute: running.execute
});
running.deps.add(subscriptions);
}
return value;
};
const writeFn = (newValue) => {
value = newValue;
for (const sub of [...subscriptions]) {
sub.execute();
}
};
return [readFn, writeFn];
};

const createEffect = (fn) => {
const execute = () => {
running.deps.clear();
context.push(running);
try {
fn();
} finally {
context.pop(running);
}
};

const running = {
execute,
deps: new Set()
};
execute();
};

const createMemo = (fn) => {
const [memo, setMemo] = createSignal();
createEffect(() => setMemo(fn()));
return memo;
};

const [name, setName] = createSignal("a");
const fullName = createMemo(() => {
return "c-" + name();
});
createEffect(() => console.log(name(), fullName()));
setName("b");

Signals是一個(gè)基礎(chǔ)的數(shù)據(jù)更新與讀取,Reactions 是可以追蹤訂閱到 Signals 的變化,所以在 Reactions 函數(shù)里設(shè)置 Derivations 的值。

五、最后

本文是學(xué)習(xí)Signals的一些記錄。希望能通過介紹響應(yīng)式狀態(tài)管理的一些歷史和理念,讓你對狀態(tài)管理有全面的認(rèn)識,如果感覺本文介紹的不夠詳細(xì),可以閱讀下面的引用原文。

六、引用

  1. ??https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob??
  2. ??https://dev.to/this-is-learning/react-vs-signals-10-years-later-3k71??
  3. ??https://mp.weixin.qq.com/s/Tn0rbkCdFw4f-3ihKUEYQA??
  4. ??https://indepth.dev/posts/1289/solidjs-reactivity-to-rendering??
  5. ??https://preactjs.com/guide/v10/signals/??
  6. ??https://preactjs.com/blog/introducing-signals??

圖片

責(zé)任編輯:武曉燕 來源: 大轉(zhuǎn)轉(zhuǎn)FE
相關(guān)推薦

2016-08-12 11:04:17

JavaScript物聯(lián)網(wǎng)應(yīng)用

2021-05-06 05:37:40

JavascriptSTT機(jī)器學(xué)習(xí)

2022-04-27 19:05:46

.NETJavaScript接口

2024-08-27 08:35:43

JavaScriptPromise模式

2017-09-04 14:40:00

LimitLatchTomcat線程

2020-05-22 10:40:33

ContinuatioJS前端

2009-02-27 16:22:34

AjaxProAjax.NET

2024-05-10 08:38:01

JavaScriptPiniaVuex

2018-10-11 10:38:31

前端JavaScript編程語言

2021-06-03 10:00:47

JavaScript 前端數(shù)克隆對象

2009-06-25 15:54:18

設(shè)計(jì)模式EJB

2010-08-09 10:21:56

XMLFlex

2011-06-23 09:14:52

CRM云計(jì)算

2010-10-08 10:15:34

IFrameJS控件

2009-02-03 10:19:45

2010-08-03 11:07:34

NFSVMware快照

2009-06-29 17:09:49

JavaBeanJSP

2022-06-28 08:02:44

SPISpringJava

2022-06-30 20:47:58

區(qū)塊鏈

2020-05-06 07:53:09

物聯(lián)網(wǎng)物流IOT
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 夜久久 | 亚洲视频在线观看 | 精品综合在线 | 成人一区二区视频 | 一区二区激情 | av香港经典三级级 在线 | 一区二区三区久久久 | 亚洲最新在线视频 | 日韩在线h| 欧美一区二区三区四区视频 | 精品国产乱码一区二区三区 | 亚洲精品中文字幕 | 天天射中文 | 国产成人福利在线观看 | 在线免费av观看 | 国产二区三区 | 成人在线精品视频 | 中文字幕亚洲视频 | 天天天天天天天干 | 国产精品美女久久久久久久久久久 | 香蕉婷婷 | av午夜电影 | 日韩a视频 | 欧洲av在线 | 极品粉嫩国产48尤物在线播放 | 91视频进入 | 免费一区二区三区 | 日日夜夜精品免费视频 | 国产小视频在线 | 一区二区三区国产好 | 亚洲精品久久久久久国产精华液 | 欧美综合自拍 | 91传媒在线观看 | 久久久久久久91 | 亚洲精品久久久久中文字幕二区 | 在线精品一区二区三区 | 亚洲精品在线视频 | 91丨九色丨国产在线 | 成人国内精品久久久久一区 | 国产精品久久久久久久久久免费看 | 91精品国产777在线观看 |