#javascript #callback #dom-events
#javascript #обратный вызов #dom-события
Вопрос:
У меня есть объектный литерал, возвращаемый функцией, и, в свою очередь, этот объект создает iframe и выполняет несколько действий, когда DOM загружается в этот iframe. Я хочу иметь возможность «получить» значение, возвращаемое обратным вызовом при запуске события. Вот упрощенный объект:
var myFunc = function (url) {
return {
url: url,
myMethod: function () {
// some code here to create my iframe.
var callbackFunc = function (event) {
// do some stuff with the dom.
return aValueAsynchronously;
};
var async = my_iframe.addEventListener("DOMContentLoaded", callbackFunc, true);
my_iframe.src = this.url;
}
}
}
После прочтения этого кода я использую его как следовать за ним:
var myValue = myFunc.myMethod('http://www.example.org');
и когда example.org завершается загрузка в iFrame, DOMContentLoaded
запускается обратный вызов, и возвращается значение (после некоторой логики). Как мне присвоить это значение myValue
(строка выше)? Я понимаю, что для этого мне нужно использовать обратный вызов, но где и как?
Ответ №1:
Во-первых, приведенный вами код не может быть вызван myFunc.myMethod
, поскольку значение функции не имеет myMethod
свойства. Вместо этого функция возвращает объект с этим свойством. Итак, для начала вам нужно:
var myValue = myFunc('http://foo.com').myMethod();
Однако это приведет только к вызову метода, который устанавливает обратный вызов. Чтобы на самом деле иметь доступ к aValueAsynchronously
, вы могли бы создать замыкание вокруг этого значения:
var myFunc = function(url){
var aValueAsynchronously;
return {
val : aValueAsynchronously,
myMethod: function(){
var callback = function(evt){
aValueAsynchronously = ...;
};
...register your callback...
}
};
};
var obj = myFunc('http://foo.com');
obj.myMethod();
...some time passes, and eventually the callback occurs...
console.log( obj.val ); // This will be what was set in your callback
Однако вместо этого я бы лично написал код, чтобы я мог передать свой собственный обратный вызов для выполнения из обратного вызова iframe и просто передать специальное значение моему обратному вызову напрямую. (Это звучит запутанно; см. Код ниже.) Таким образом, вам не нужно ждать, пока значение станет доступным, а скорее вы получите уведомление, когда оно будет доступно:
var myFunc = function(url,whenDone){
return {
myMethod: function(){
var callback = function(evt){
var aValueAsynchronously = ...;
whenDone(aValueAsynchronously);
};
...register your callback...
}
};
};
var myObj = myFunc('http://foo.com',function(specialValue){
// use specialValue here
});
myObj.myMethod(); // Go
Комментарии:
1. Спасибо за ваш ответ! Я попробую два описанных вами решения и посмотрю, как это работает! 🙂
2. Мне нравится второе решение с прямой передачей значения обратного вызова! Это действительно демонстрирует силу JS! Еще раз спасибо!
Ответ №2:
Если myValue находится в области для обратного вызова, просто назначьте ему. Если он не входит в область видимости, то к нему необходимо обращаться как к свойству некоторого объекта, и ссылка на этот объект должна быть в области видимости для обратного вызова.
В простом случае, если myValue является глобальным, и вы ожидаете, что код будет выполняться в браузере, тогда обратный вызов может быть установлен window.myValue = ...;
. В противном случае обратный вызов должен получить к нему доступ как к свойству глобального объекта (что эквивалентно window в браузере).
Итак, в вашей функции у вас может быть:
var callbackFunc = function (event) {
// do some stuff with the dom.
window.myValue = aValueAsynchronously;
return aValueAsynchronously;
};
Или я полностью упустил суть?
Комментарии:
1. Спасибо, но я не запускаю это в браузере! Решение Phrogz сработало.
2. Затем вы можете получить ссылку на глобальный объект и использовать его вместо этого. Но да, я думаю, что Phrogz понял это.