Vue.js设计与实现无限递归学习总结

作者:玛拉_以琳 时间:2024-04-28 10:53:53 

栈溢出

const data = { foo: 1 }
const obj = new Proxy(data, {/*...*/})
effect(() => obj.foo = obj.foo + 1)

此项操作会引起栈溢出:

Uncaught RangeError: Maximum call sack size exceeded

在此操作中, 会先读取obj.foo的值, 这会触发track操作, 将副作用函数入栈, 此时有加一并赋值, 此时会触发trigger操作, 将副作用函数出栈并执行, 在这种情况下, 该副作用函数还在执行中, 又开始下一次的执行, 导致无限递归调用自己导致栈溢出报错.

在这个操作中读取与设置的是同一个副作用函数activeEffect, 因此在trigger要触发时添加条件: 如果trigger触发的副作用函数与当前执行的副作用函数相同, 则不触发执行:

function trigger (target, key) {
   const depsMap = bucket.get(target)
   if (!depsMap) return
   const effects = depsMap.get(key)
   const effectsToRun = new Set()
   effects && effects.forEach(effectFn => {
       if (effectFn !== activeEffect) {
           effectsToRun.add(effectFn)
       }
   })
   effectsToRun.forEach(effectFn => effectFn())
}

目前为止响应式完整代码

// 储存副作用函数的桶
 const bucket = new WeakMap()
 // 用于储存被注册的副作用的函数
 let activeEffect = undefined
 // 副作用函数栈
 const effectStack = []
 function cleanup (effectFn) {
   for (let itme of effectFn.deps) {
     itme.delete(effectFn)
   }
   effectFn.deps.length = []
 }
 function effect (fn) {
   const effectFn = () => {
       cleanup(effectFn)
       // 调用当前的副作用函数时, 赋值给 全局变量
       activeEffect = effectFn
       // 在调用副作用函数之前将该函数压入栈
       effectStack.push(effectFn)
       fn()

来源:https://segmentfault.com/a/1190000042308922

标签:Vue.js,无限递归
0
投稿

猜你喜欢

  • python使用plot绘制未来15天气温折线图

    2022-11-06 02:09:41
  • Python代码需要缩进吗

    2022-05-07 18:21:15
  • 使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法

    2024-05-13 09:29:36
  • MySQL数据库的事务和索引详解

    2024-01-21 00:40:48
  • php利用反射实现插件机制的方法

    2024-05-13 09:20:48
  • 千篇一律的JS运算符讲解,一起来看看

    2024-05-13 10:06:52
  • Python 使用 Pillow 模块给图片添加文字水印的方法

    2022-06-13 04:13:37
  • python网络爬虫精解之Beautiful Soup的使用说明

    2021-02-21 15:20:48
  • python中的测试框架

    2023-02-16 03:59:08
  • MySQL子查询的使用详解上篇

    2024-01-28 00:58:13
  • ADO.NET通用数据库访问类

    2024-01-28 03:26:19
  • CSS背景属性5个应用实例

    2009-09-13 20:54:00
  • 对pandas中两种数据类型Series和DataFrame的区别详解

    2021-08-05 04:09:38
  • python logging 重复写日志问题解决办法详解

    2021-04-29 13:19:30
  • Oracle数据库逻辑备份的SH文件

    2010-07-27 13:26:00
  • Python列表删除元素del、pop()和remove()的区别小结

    2021-12-02 07:32:41
  • Python中常见的反爬机制及其破解方法总结

    2023-03-05 19:38:42
  • JS、CSS和HTML实现注册页面

    2024-04-17 10:03:20
  • Python应用库大全总结

    2023-05-14 01:57:19
  • python学习实操案例(二)

    2022-09-04 01:36:41
  • asp之家 网络编程 m.aspxhome.com