Наблюдайте за объектом, который мы не можем изменить с помощью прокси - PullRequest
0 голосов
/ 03 января 2019

Я хочу наблюдать за объектом, используя Прокси, объект из игры, которую я не создал.Я нашел это как ответ на другой вопрос:

var proxied = new Proxy(foo, {
    get: function(target, prop) {
        console.log({
            type: "get",
            target,
            prop
        })
        return Reflect.get(target, prop)
    },
    set: function(target, prop, value) {
        console.log({
            type: "set",
            target,
            prop,
            value
        })
        return Reflect.set(target, prop, value)
    }
})

Если я изменю это, я должен сделать proxied.bar = "Hello world".Но я не изменяю это, игра делает;и это не делает это так.(он делает foo.bar = ..., они не используют прокси ...) Итак, что я могу сделать, чтобы наблюдать за массивом?Спасибо.

1 Ответ

0 голосов
/ 08 января 2019

Существует не так много вариантов, чтобы можно было наблюдать, изменился ли объект или нет.Раньше мы могли использовать Object.observe() или Object.watch(), но оба они устарели и больше не являются надежными.

Прокси-серверы - единственный вариант, но, очевидно, игра должна использовать прокси-объект для того, чтобыловушка для попадания.

Я не совсем знаю, что вы можете сделать с точки зрения манипуляции с исходным объектом foo, но вместо создания объекта proxied установите foo на точкук своему собственному прокси.Другими словами,

foo = new Proxy(foo, {
    get: function(target, prop) {
        console.log({
            type: "get",
            target,
            prop
        })
        return Reflect.get(target, prop)
    },
    set: function(target, prop, value) {
        console.log({
            type: "set",
            target,
            prop,
            value
        })
        return Reflect.set(target, prop, value)
    }
})

Если вы можете напрямую манипулировать игровым объектом, например, в ловушках get и set вы можете передавать свои собственные функции обратного вызова и наблюдать за любыми изменениями вэтот объект.

Возможно, вы не сможете переназначить foo (если он был объявлен с const).В этом случае есть обходной путь, но он немного неуклюжий и не синхронный, как в описанном выше подходе.

По сути, вы можете создать функцию, которая создает кэш записей в объекте foo, и назаданный интервал перепроверяет foo на любые изменения и выполняет любую указанную логику обратного вызова.Я не могу быть слишком конкретным, потому что детали реализации действительно основаны на структуре foo ( например , ее вложенности и типах объектов, которые она может содержать - будь то даты, ссылки на функции илимного других видов объектов).

Базовая реализация может выглядеть так:

foo = { ... } // whatever kind of object foo is

function observeFoo() {
    const entries = Object.entries(foo);

    // initialize cache if we don't have one
    if (!observeFoo.cache) observeFoo.cache = {};

    // begin checking keys in cache
    entries.forEach(entry => {
        const [ key, value ] = entry;
        if (observeFoo.cache[key] !== value) {
            // do something regarding this change
        }

        // update cache
        observeFoo.cache[key] = value;
   });
}

setInterval(observeFoo, 1000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...