Подтвердить что ты не робот

Хотя переменная не определена - подождите

У меня есть событие click, которое запускается из другого места автоматически в первый раз. Моя проблема заключается в том, что он работает слишком быстро, поскольку требуемые переменные все еще определяются Flash и веб-службами. Поэтому прямо сейчас у меня есть:

(function ($) {
    $(window).load(function(){
        setTimeout(function(){
            $('a.play').trigger("click");
        }, 5000);
    });
})(jQuery);

Проблема в том, что 5 секунд для человека с медленным подключением к Интернету может быть слишком быстрым, и наоборот, для человека с быстрым подключением к Интернету он слишком медленный.

Итак, как мне сделать задержку или таймаут, пока не будет определен someVariable?

4b9b3361

Ответ 1

Я бы предпочел этот код:

function checkVariable() {

   if (variableLoaded == true) {
       // Here is your next action
   }
 }

 setTimeout(checkVariable, 1000);

Ответ 2

Следующее будет продолжать поиск someVariable, пока он не будет найден. Он проверяет каждые 0,25 секунды.

function waitForElement(){
    if(typeof someVariable !== "undefined"){
        //variable exists, do what you want
    }
    else{
        setTimeout(waitForElement, 250);
    }
}

Ответ 3

С Ecma Script 2017 Вы можете использовать async-wait и вместе, чтобы сделать это. И пока не произойдет сбой или блокировка программы, даже переменная никогда не будет правдой

//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);
/////////////////////////////////////////////////////////////

Ответ 4

Вместо использования события загрузки Windows используйте готовое событие в документе.

$(document).ready(function(){[...]});

Это должно срабатывать, когда все в DOM готово к работе, включая полностью загруженный мультимедийный контент.

Ответ 5

Здесь пример, в котором вся логика ожидания до тех пор, пока не будет установлена ​​переменная, будет отложена до функции, которая затем вызывает обратный вызов, который делает все остальное, что требуется программе - если вам нужно загружать переменные перед тем, как делать что-либо еще, это чувствует как опрятный способ сделать это, так что вы отделяете переменную загрузку от всего остального, при этом все же обеспечение "всего остального" по сути является обратным вызовом.

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

  });

Ответ 6

async, await реализации, улучшение по сравнению с ответом @Toprak

(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");

После пересмотра ОП вопрос. На самом деле есть лучший способ реализовать то, что предполагалось: "обратный вызов набора переменных". Хотя приведенный ниже код работает только в том случае, если нужная переменная инкапсулируется объектом (или окном), а не объявлена let или var (я оставил первый ответ, потому что я просто улучшал существующие ответы, фактически не читая оригинальный вопрос):

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");
    }
});

см. Object.defineProperty или используйте прокси es6 (что, вероятно, излишне)

Ответ 7

Вы можете использовать это:

var refreshIntervalId = null;
refreshIntervalId = setInterval(checkIfVariableIsSet, 1000);

var checkIfVariableIsSet = function()
{
    if(typeof someVariable !== 'undefined'){
        $('a.play').trigger("click");
        clearInterval(refreshIntervalId);
    }
};

Ответ 8

Более короткий путь:

   var queue = function (args){
      typeof variableToCheck !== "undefined"? doSomething(args) : setTimeout(function () {queue(args)}, 2000);
};

Вы также можете передавать аргументы

Ответ 9

Вы можете заставить Flash вызвать функцию, когда она будет выполнена. Я не уверен, что вы подразумеваете под веб-сервисами. Я предполагаю, что у вас есть код JavaScript, вызывающий веб-службы через Ajax, и в этом случае вы узнаете, когда они прекратятся. В худшем случае вы можете сделать цикл setTimeout, который будет проверять каждые 100 мск или около того.

И проверка того, определена ли переменная, может быть просто if (myVariable) или безопаснее: if(typeof myVariable == "undefined")

Ответ 10

Я проголосовал за ответ @dnuttle, но в итоге использовал следующую стратегию:

// 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 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();
});

Это проверено и работает! ;)

Суть: https://gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c

Ответ 11

Object.defineProperty(window, 'propertyName', {
    set: value => {
        this._value = value;
        // someAction();
    },
    get: () => this._value
});

или даже если вы просто хотите, чтобы это свойство передавалось в качестве аргумента функции, и вам не нужно, чтобы оно было определено для глобального объекта:

Object.defineProperty(window, 'propertyName', { set: value => someAction(value) })

Однако, поскольку в вашем примере вы, похоже, хотите выполнить действие при создании узла, я бы посоветовал вам взглянуть на MutationObservers.