Как использовать прокси для просмотра, если переменная (больше не) неопределена

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

`` `

var stage = undefined
let myObj;
let st = {
    stage: stage,
}
let lr = {
    get: function(obj:any, prop:any):LightRay{
        myObj = new SomeObjThatNeedsStage(obj[prop]) // <= supposed to be non-undefined stage
        return myObj
    },
}
let p = new Proxy(st, lr)
// At this point I expect the lr handler to have been executed if the stage var has been instantiated by some external code that's out of my control.

`` `

Очевидно, я неправильно понимаю, как работает Прокси, но я пробовал различные сценарии, ни один из которых не работает. Передача неопределенного этапа в качестве цели для прокси не работает (получение Cannot create proxy with a non-object as target or handler ошибка). Как я могу использовать прокси в этом сценарии? Почему я не могу observe неопределенный этап с прокси, пока он не будет создан, а затем выполнить обратный вызов?

FYI:

Этап var является глобальным, и я не могу его контролировать (в какой-то момент он создается экземпляром create.js). Весь код выполняется из модуля UMD. Я использую машинопись (переходя на es5). Object.defineProperty() доступен в моем браузере. Кроме того, сценарий (типа createjs.Stage), когда он создается, содержит метод установки / получения другого типа, что делает его проблематичным при работе с машинописью.

2 ответа

Решение

Обновленный ответ

Вы сказали, что не контролируете, как stage установлено.

Наблюдение за изменением - это кошмар против паттернов и сопровождения кода. Ищите любое другое решение, которое вы можете, например, сделать один модуль зависимым от другого, чтобы вы знали, что он загружен до запуска вашего модуля.

Однако вы сказали, что другого пути нет, поэтому:

Вы не можете использовать Прокси для этого, потому что для того, чтобы он был эффективным, настройка кода stage придется установить его через прокси, а не напрямую.

Вы сказали, что не контролируете, как stage объявлен Это означает, что вы не можете использовать Object.defineProperty либо для этого, потому что свойство глобального объекта, которое var создает имеет configurable: false,

Если абсолютно, безусловно, нет никакого способа получить координацию между вашим модулем и чем бы то ни было stageВам придется прибегнуть к циклу таймера. Это не очень хорошая идея, но может быть вашим единственным реальным вариантом:

var stop = Date.now() + 30000;
var timer = setInterval(function() {
    if (typeof stage !== "undefined" || Date.now() > stop) {
        clearInterval(timer);
        timer = 0;
        // Your code here, if `stage` is still undefined, you hit the timeout
    }
}, 50); // 50ms interval or whatever you need

Оригинальный ответ

Безусловно, лучшее решение здесь: не делай этого. Вместо этого используйте объект с установщиком:

var stuff = {
    _stage: undefined,
    get stage() {
        return _stage;
    },
    set stage(value) {
        if (_stage === undefined && value !== undefined) {
            _stage = value;
            // Trigger your code here
        }
    }
};

Затем другой код делает этот набор stuff.stage а не настройка stage,

Если вам действительно нужно смотреть stage изменить, когда это будет определено чем-то другим, и stage глобально, тогда простое решение - использовать старый добрый получатель:

let myObj;

Object.defineProperty(window, 'stage1', {
  set (value) {
    myObj = new SomeObjThatNeedsStage(stage)
    return value
  }
})

В приведенном выше, убедитесь, что у вас нет var stage = undefined тебе это больше не нужно.

Другие вопросы по тегам