[译]JavaScript响应式的最佳解释
栏目: JavaScript · 发布时间: 6年前
内容简介:原文地址:许多前端JavaScript框架(例如Angular,React和Vue)都有自己的Reactivity引擎。通过了解响应式及其工作原理,您可以提高开发技能并更有效地使用JavaScript框架。在视频和下面的文章中,我们构建了您在Vue源代码中看到的相同类型的Reactivity。当你第一次看到它时,Vue的响应式系统看起来很神奇。拿这个简单的Vue应用程序来说:
原文地址: The Best Explanation of JavaScript Reactivity
许多前端JavaScript框架(例如Angular,React和Vue)都有自己的Reactivity引擎。通过了解响应式及其工作原理,您可以提高开发技能并更有效地使用JavaScript框架。在视频和下面的文章中,我们构建了您在Vue源代码中看到的相同类型的Reactivity。
:bulb:响应式系统
当你第一次看到它时,Vue的响应式系统看起来很神奇。拿这个简单的Vue应用程序来说:
Vue
只是知道如果
price
改变,它应该做三件事:
- 更新网页上
price
的值。 - 重新计算乘法表达式
price * quantity
,并更新页面。 - 再次调用函数
totalPriceWithTax
并更新页面。 但是等等,你是否会好奇,Vue如何知道price
更改时所要更新的内容,以及它如何跟踪所有内容?
我们解决一个大问题是通常不会这样编程。例如,如果我运行如下代码:
你觉得它打印什么?由于我们没有使用Vue,它将打印出来 10
。
在Vue中,我们希望 total
随着 price
或 quantity
更新而更新。我们想要:
不幸的是,JavaScript是程序性的,而不是响应式的,所以这在现实中不起作用。为了实现 total
响应,我们必须使用JavaScript来使事情表现得与众不同。
:warning: 问题
我们需要保存如何计算得到 total
,这样可以在 price
或 quantity
更新时重新运行它,
:white_check_mark: 解决方案
首先,需要一些方法告诉我们的应用程序,“我即将运行的代码, 存储它 ,我可能需要在其他时间运行它。”然后我们开始运行代码,如果 price
或 quantity
变量得到更新,再次运行存储的代码。
我们可以通过记录函数来执行此操作,以便我们可以再次运行它。
target
变量中存储了一个匿名函数,然后调用一个
record
函数。使用ES6箭头语法我也可以这样写:
record
函数定义很简单:
target
(在我们的例子中
{ total = price * quantity }
),所以我们可以稍后运行它,可以通过一个
replay
函数来运行存储的所有内容。
storage
数组中存储的所有匿名函数。 然后在代码中,我们可以:
很简单吧?如果您需要阅读并尝试再次理解它,这里有完整的代码,仅供参考,如果您想知道原因,我会以特定的方式对此进行编码。
:warning: 问题
我们可以根据需要继续记录 target
,但是有一个更强大的解决方案可以扩展我们的应用程序。一个负责维护 target
列表的类,当需要它们重新运行时,这些 target
列表会得到通知。
:white_check_mark: 解决方案:依赖类
我们解决这个问题的一种方法是将这种行为封装到它自己的类中,这是一个实现标准观察者模式的依赖类。
因此,如果我们创建一个JavaScript类来管理我们的依赖项(它更接近Vue的处理方式),它可能看起来像这样:
subscribers
而不是
storage
。我们现在调用的函数是
depend
而不是
record
,我们现在使用
notify
而不是
replay
。为了让这个运行:
target
。
:warning: 问题
我们将为每个变量设置一个 Dep
类,并且很好地封装了创建需要监视更新的匿名函数的行为。也许一个 watcher
函数可能是为了处理这种行为。
所以不要这样调用:
(这只是上面的代码) 我们可以改为:
:white_check_mark: 解决方案:观察者函数
在我们的 Watcher
函数中,我们可以做一些简单的事情:
watcher
函数接受一个
myFunc
参数,将其设置为全局
target
属性,调用
dep.depend()
将
target
添加到订阅者
subscriber
,执行
target
函数,然后重置
target
函数。
现在,当我们运行以下内容时:
您可能想知道为什么我们将target设为全局变量,而不是将其传递到我们需要的函数中。这将在我们的文章结尾处解释。
:warning: 问题
我们有一个单独的 Dep class
,但我们真正想要的是每个变量都有自己的 Dep
。在继续之前,将数据设为对象属性。
price
和
quantity
)都有自己的内部
Dep
类。
现在我们执行时:
data.price
的值,我希望
price
属性的
Dep
类将存储在
target
的匿名函数推送到其
subscriber
数组(通过调用
dep.depend()
)。由于
data.quantity
被访问,我还希望
quantity
属性
Dep
类将存储在
target
的匿名函数推送到其
subscriber
数组中。
data.price
被访问,我希望它只是推送到
price
属性
Dep
类。
price
的
subscribers
什么时候调用
dep.notify()
?我希望在
price
设置时调用它们。在文章的最后,我希望能够进入控制台并执行:
price
或
quantity
),所以当它被访问时,我们可以保存
target
到我们的
subscribers
数组中,当它被更改时,运行存储在
subscribers
数组中的函数。
:white_check_mark: 解决方案:Object.defineProperty()
我们需要了解 Object.defineProperty() 函数,它是简单的ES5 JavaScript。它允许我们为属性定义 getter
和 setter
函数。在我向您展示如何在 Dep
类中使用它之前,将向您展示最基本的用法。
如您所见,它只记录两行。但是,它实际上没有 get
或 set
任何值,因为我们过度使用了该功能。我们现在加回来吧。 get()
期望返回一个值, set()
仍然需要更新一个值,所以让我们添加一个 internalValue
变量来存储我们当前的 price
值。
既然我们的 get
和 set
工作正常,您认为将打印到控制台的是什么?
get
并
set
值时,我们可以获得通知。通过一些递归,我们可以为数据数组中的所有项运行它,对吧?
Object.keys(data)
返回对象键的数组。
现在一切都有 getter
和 setter
,我们在控制台上看到了这一点。
将两种想法放在一起
price
值时,我们想要
price
记住这个匿名函数
(target)
。这样,如果
price
被更改,或者
set
为新值,它将触发此函数以重新运行,因为它知道此行依赖于它。
Get=>记住当前匿名函数,当我们的值发生变化时,会再次运行它。
Set=>运行保存的匿名函数,我们的值随之改变。
或者就我们的 Dep Class
而言
Price accessed (get)=>调用 dep.depend()
以保存当前 target
Price set=>调用 dep.notify()
给 price
,重新运行全部 targets
让我们结合这两个想法,并完成我们的最终代码。
现在看看我们执行时会发生什么。
正是我们所希望的! price
和 quantity
确实都响应了!每当值 price
或 quantity
更新时,全部的代码都会重新运行。
Vue文档中的这个插图现在应该开始有意义了。
你看到那个美丽的紫色数据圈 getters and setters
了吗?看起来应该很熟悉!每个组件实例都有一个 watcher
实例(蓝色),它从 getter
(红线)收集依赖项。稍后调用 setter
时,它会 通知 watcher
导致组件重新渲染。注释之后的图如下。
是的,这现在不是更有意义吗?
显然,Vue如何做到这一点更复杂,但你现在知道了基础知识。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 从朴素解释出发解释leveldb的设计
- 理解响应者和响应链如何处理事件
- 从源码解析vue的响应式原理-响应式的整体流程
- 干货 | 解释 ReGenesis 构想
- JavaScript 预解释分析
- jQuery 安全模型解释
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
《Unity3D网络游戏实战(第2版)》
罗培羽 / 机械工业出版社 / 2019-1-1 / 89.00元
详解Socket编程,搭建稳健的网络框架;解决网游中常见的卡顿、频繁掉线等问题;探求适宜的实时同步算法。完整的多人对战游戏案例,揭秘登录注册、游戏大厅、战斗系统等模块的实现细节。 想要制作当今热门的网络游戏,特别是开发手机网络游戏,或者想要到游戏公司求职,都需要深入了解网络游戏的开发技术。本书分为三大部分,揭示网络游戏开发的细节。 第一部分“扎基础”(1-5章) 介绍TCP网络游......一起来看看 《《Unity3D网络游戏实战(第2版)》》 这本书的介绍吧!