Как использовать прокси для просмотра, если переменная (больше не) неопределена
Пожалуйста, прости мою 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
тебе это больше не нужно.