Document
Document

simulate simplicity mvvm trigger() throw index.html:72 Uncaught RangeError: Maximum call stack size exceeded

15 views Asked by At
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="foo"></div>
    <div id="foo1"></div>
    <script>
        function reactive(obj) {
            return new Proxy(obj, {
                get(target, key, receiver) {
                    track(target, key)
                    return target[key]
                },
                set(target, key, value, receiver) {
                    target[key] = value
                    trigger(target, key)
                }
            })
        }

        const targetMap = new Map()

        function track(target, key) {
            if (activeEffect) {
                let depsMap = targetMap.get(target)
                if (!depsMap) {
                    targetMap.set(target, (depsMap = new Map()))
                }
                let dep = depsMap.get(key)
                if (!dep) {
                    depsMap.set(key, (dep = new Set()))
                }
                dep.add(activeEffect)
            }
        }

        function trigger(target, key) {
            const depsMap = targetMap.get(target)
            if (!depsMap) return
            let deps = depsMap.get(key)
            if (deps) {
                const effectToRun = new Set();
                deps && deps.forEach(effect => {
                    if (effect !== activeEffect) {
                        effectToRun.add(effect)
                    }
                });
                effectToRun.forEach(effect => effect())
            }
        }

        function whenDepsChange(update) {
            const effect = () => {
                activeEffect = effect
                update()
                activeEffect = null
            }
            effect()
        }

        let fooEl = document.getElementById('foo')
        let foo1El = document.getElementById('foo1')
        let foo = reactive({ c: 1 })

        whenDepsChange(() => {
            fooEl.innerHTML = foo.c
            console.log(foo.c);
            foo.c = 1
        })
        whenDepsChange(() => {
            foo1El.innerHTML = foo.c + 'test'
            console.log(foo.c);
            foo.c = 3
        })

        foo.c = 1000
        foo.c++

    </script>
</body>

</html>

enter image description here

i hope this simple example can make the effect function work properly instead of recursively reporting errors

How to rewrite the code to avoid recursive calls? Any help would be greatly appreciated How to rewrite the code to avoid recursive calls? Any help would be greatly appreciated

0

There are 0 answers