Ich habe ein click
-Ereignis, das zum ersten Mal automatisch von einer anderen Stelle ausgelöst wird. Mein Problem ist, dass es zu früh läuft, da die erforderlichen Variablen immer noch von Flash und Webservices definiert werden. So jetzt habe ich:
(function ($) {
$(window).load(function(){
setTimeout(function(){
$('a.play').trigger("click");
}, 5000);
});
})(jQuery);
Das Problem ist, dass 5 Sekunden für eine Person mit einer langsamen Internetverbindung zu schnell sein könnten und umgekehrt, für eine Person mit einer schnellen Internetverbindung ist es zu langsam.
Wie soll ich also die Verzögerung oder das Timeout durchführen, bis someVariable
definiert ist?
Ich würde diesen Code vorziehen:
function checkVariable() {
if (variableLoaded == true) {
// Here is your next action
}
}
setTimeout(checkVariable, 1000);
Im Folgenden wird nach someVariable gesucht, bis es gefunden wird. Es wird alle 0,25 Sekunden geprüft.
function waitForElement(){
if(typeof someVariable !== "undefined"){
//variable exists, do what you want
}
else{
setTimeout(waitForElement, 250);
}
}
async, await
Implementierung, Verbesserung gegenüber @ Toprak Antwort
(async() => {
console.log("waiting for variable");
while(!window.hasOwnProperty("myVar")) // define the condition as you like
await new Promise(resolve => setTimeout(resolve, 1000));
console.log("variable is defined");
})();
console.log("above code doesn't block main function stack");
Nach erneuter Prüfung der Frage des OP. Es gibt tatsächlich eine bessere Möglichkeit, das zu implementieren, was beabsichtigt war: "Variablen-Set-Callback". Obwohl der folgende Code nur funktioniert, wenn die gewünschte Variable von einem Objekt (oder einem Fenster) eingekapselt wird, anstatt von let
oder var
deklariert zu werden (ich habe die erste Antwort hinterlassen, weil ich gerade eine Verbesserung gegenüber der vorhandenen vorgenommen habe Antworten, ohne die ursprüngliche Frage tatsächlich zu lesen):
let obj = encapsulatedObject || window;
Object.defineProperty(obj, "myVar", {
configurable: true,
set(v){
Object.defineProperty(obj, "myVar", {
configurable: true, enumerable: true, writable: true, value: v });
console.log("window.myVar is defined");
}
});
siehe Object.defineProperty oder benutze es6 proxy (was wahrscheinlich übertrieben ist)
Hier ein Beispiel, bei dem die gesamte Logik für das Warten, bis die Variable gesetzt ist, auf eine Funktion verschoben wird, die dann einen Rückruf aufruft, der alles andere tut, was das Programm tun muss Auf diese Weise trennen Sie das Laden der Variablen von allem anderen und stellen gleichzeitig sicher, dass "alles andere" im Wesentlichen ein Rückruf ist.
var loadUser = function(everythingElse){
var interval = setInterval(function(){
if(typeof CurrentUser.name !== 'undefined'){
$scope.username = CurrentUser.name;
clearInterval(interval);
everythingElse();
}
},1);
};
loadUser(function(){
//everything else
});
Verwenden Sie anstelle des Windows-Ladeereignisses das Ready-Ereignis für das Dokument.
$(document).ready(function(){[...]});
Dies sollte ausgelöst werden, wenn alles im DOM einsatzbereit ist, einschließlich vollständig geladener Medieninhalte.
Mit Ecma Script 2017 können Sie async-await und, während dies zusammen ausgeführt wird, verwenden Und während die Programmvariable nicht abstürzt oder gesperrt wird, ist sie niemals wahr
//First define some delay function which is called from async function
function __delay__(timer) {
return new Promise(resolve => {
timer = timer || 2000;
setTimeout(function () {
resolve();
}, timer);
});
};
//Then Declare Some Variable Global or In Scope
//Depends on you
let Variable = false;
//And define what ever you want with async fuction
async function some() {
while (!Variable)
await __delay__(1000);
//...code here because when Variable = true this function will
};
////////////////////////////////////////////////////////////
//In Your Case
//1.Define Global Variable For Check Statement
//2.Convert function to async like below
var isContinue = false;
setTimeout(async function () {
//STOPT THE FUNCTION UNTIL CONDITION IS CORRECT
while (!isContinue)
await __delay__(1000);
//WHEN CONDITION IS CORRECT THEN TRIGGER WILL CLICKED
$('a.play').trigger("click");
}, 1);
/////////////////////////////////////////////////////////////
In diesem Fall müssen Sie setTimeout nicht verwenden, sondern nur die asynchrone Funktion ...
Kürzerer Weg:
var queue = function (args){
typeof variableToCheck !== "undefined"? doSomething(args) : setTimeout(function () {queue(args)}, 2000);
};
Sie können auch Argumente übergeben
Sie können dies verwenden:
var refreshIntervalId = null;
refreshIntervalId = setInterval(checkIfVariableIsSet, 1000);
var checkIfVariableIsSet = function()
{
if(typeof someVariable !== 'undefined'){
$('a.play').trigger("click");
clearInterval(refreshIntervalId);
}
};
Sie könnten Flash dazu bringen, die Funktion aufzurufen, wenn sie fertig ist. Ich bin mir nicht sicher, was Sie mit Webservices meinen. Ich gehe davon aus, dass Sie JavaScript-Code haben, der Web-Services über Ajax aufruft. In diesem Fall wissen Sie, wann sie beendet werden. Im schlimmsten Fall können Sie einen Schleifen setTimeout
ausführen, der alle 100 ms überprüft wird.
Die Prüfung, ob eine Variable definiert ist oder nicht, kann nur if (myVariable)
oder sicherer sein: if(typeof myVariable == "undefined")
Object.defineProperty(window, 'propertyName', {
set: value => {
this._value = value;
// someAction();
},
get: () => this._value
});
oder auch, wenn diese Eigenschaft nur als Argument an eine Funktion übergeben werden soll und nicht für ein globales Objekt definiert werden muss:
Object.defineProperty(window, 'propertyName', { set: value => someAction(value) })
Da Sie in Ihrem Beispiel jedoch scheinbar beim Erstellen eines Knotens eine Aktion ausführen möchten, würde ich Ihnen vorschlagen, einen Blick auf MutationObservers .
Ich habe @ dnuttle's answer auf den neuesten Stand gebracht, aber am Ende habe ich folgende Strategie angewandt:
// On doc ready for modern browsers
document.addEventListener('DOMContentLoaded', (e) => {
// Scope all logic related to what you want to achieve by using a function
const waitForMyFunction = () => {
// Use a timeout id to identify your process and purge it when it's no longer needed
let timeoutID;
// Check if your function is defined, in this case by checking its type
if (typeof myFunction === 'function') {
// We no longer need to wait, purge the timeout id
window.clearTimeout(timeoutID);
// 'myFunction' is defined, invoke it with parameters, if any
myFunction('param1', 'param2');
} else {
// 'myFunction' is undefined, try again in 0.25 secs
timeoutID = window.setTimeout(waitForMyFunction, 250);
}
};
// Initialize
waitForMyFunction();
});
Es ist getestet und funktioniert! ;)
Gist: https://Gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c