javascript функция изчакайте, докато друга функция завърши

Имам две javascript функции, които се извикват от android. След дълги сесии за отстраняване на грешки най-накрая разбрах, че проблемът възниква от факта, че втората функция се извиква, преди първата да е приключила. Вече търсих примерите с отложено и т.н., но всички те зависят от извикванията на функция в друга.

function FunctInit(someVarible){ //someVariable is sent from android, cannot call again from getResult
//init and fill screen
}

function getResult(){ //also getResult need to be called from android via button
//return some variables
}

Как мога да принудя getResult да изчака FuncInit? Има ли начин да се постигне това чрез Javascript?


person tugce    schedule 09.07.2014    source източник
comment
Можете ли да зададете флаг isInitialized и да заспивате в getResult, ако все още не е обърнат?   -  person Andrew Walters    schedule 09.07.2014
comment
FunctInit Изпълнява ли някакво асинхронно действие, чието завършване също искате да изчакате?   -  person Paul S.    schedule 09.07.2014
comment
@PaulS. да, той също извиква две функции, които трябва да бъдат завършени преди getResult   -  person tugce    schedule 09.07.2014
comment
Може да искате да прочетете неща за обратните повиквания. Вижте това например: recurial.com/programming/ Това е труден за разбиране, но мощен и със сигурност добро решение за вашия проблем.   -  person Lord Grosse Jeanine    schedule 09.07.2014
comment
Надявам се да отбележите отговора, така че не искам да публикувам там, вижте тук за stackoverflow.com/questions/12116505/   -  person Anto King    schedule 09.07.2014
comment
@AntoKing отбеляза, защото посочих ясно във въпроса си, че две функции се извикват чрез android, те не трябва да се извикват взаимно в рамките на javascript   -  person tugce    schedule 09.07.2014


Отговори (3)


По мое мнение отложените/обещания (както споменахте) е правилният начин, вместо да използвате изчакване.

Ето един пример, който току-що написах, за да демонстрирам как можете да го направите с помощта на deferreds/ обещания.

Отделете малко време, за да си поиграете с отложените. След като наистина ги разберете, става много лесно да изпълнявате асинхронни задачи.

Надявам се това да помогне!

$(function(){
    function1().done(function(){
        // function1 is done, we can now call function2
        console.log('function1 is done!');

        function2().done(function(){
            //function2 is done
            console.log('function2 is done!');
        });
    });
});

function function1(){
    var dfrd1 = $.Deferred();
    var dfrd2= $.Deferred();

    setTimeout(function(){
        // doing async stuff
        console.log('task 1 in function1 is done!');
        dfrd1.resolve();
    }, 1000);

    setTimeout(function(){
        // doing more async stuff
        console.log('task 2 in function1 is done!');
        dfrd2.resolve();
    }, 750);

    return $.when(dfrd1, dfrd2).done(function(){
        console.log('both tasks in function1 are done');
        // Both asyncs tasks are done
    }).promise();
}

function function2(){
    var dfrd1 = $.Deferred();
    setTimeout(function(){
        // doing async stuff
        console.log('task 1 in function2 is done!');
        dfrd1.resolve();
    }, 2000);
    return dfrd1.promise();
}
person Antoine Cloutier    schedule 09.07.2014
comment
Защо обгръщате функциите си в $.when()? Няма нужда. Можете просто да направите function1().done() - изобщо няма нужда от $.when() там. $.when() се използва, когато имате няколко обещания и искате да знаете кога всички са готови, но не предоставя никаква полза, когато предавате само едно обещание. - person jfriend00; 09.07.2014
comment
Много сте прав, в началото имах много обещания и просто забравих да премахна $.when. Забелязах го почти по същото време, когато коментирахте. Благодаря, че го посочи! - person Antoine Cloutier; 09.07.2014
comment
Благодаря много за примера. Много добър подход е да се обясни чрез прост пример @AntoineCloutier - person samsri; 18.09.2015
comment
Съжалявам, че наистина не разбирам как работи, така че просто следвам примера. Когато извикам функцията с .done, получавам грешка Не мога да прочета свойството 'done' на undefined. - person chourn solidet; 30.12.2016
comment
здравей @AntoineCloutier. Не разбирам много за отложеното, но просто искам да знам защо все още използваш изчакване, вместо да използваш само отложено? - person Fai Zal Dong; 11.08.2017
comment
@AntoineCloutier Това наистина е добре написано и обяснено, успях да копирам вашия пример, да премахна изчакванията и да го накарам да работи перфектно за AJAX манипулатор, от който се нуждаех. Обикновено не бих коментирал извън контекста, но исках да ви благодаря, тъй като сега имам много ясно разбиране как работят done(), resolve() и promise(), преди публикацията ви [keyword_stuff] верижно свързвах setTimeout към справяне със състезателните условия (никога повече няма да правя това, виждайки колко е мързеливо). Благодаря ти. - person Christian Žagarskas; 31.05.2018
comment
@AntoineCloutier Можете ли да погледнете този въпрос stackoverflow.com/q/56397604/4425004 с това текущо решение? - person Pranesh Janarthanan; 07.06.2019

Има няколко начина, за които се сещам да направя това.

Използвайте обратно повикване:

 function FunctInit(someVarible){
      //init and fill screen
      AndroidCallGetResult();  // Enables Android button.
 }

 function getResult(){ // Called from Android button only after button is enabled
      //return some variables
 }

Използвайте изчакване (това вероятно би било моето предпочитание):

 var inited = false;
 function FunctInit(someVarible){
      //init and fill screen
      inited = true;
 }

 function getResult(){
      if (inited) {
           //return some variables
      } else {
           setTimeout(getResult, 250);
      }
 }

Изчакайте да се извърши инициализацията:

 var inited = false;
 function FunctInit(someVarible){
      //init and fill screen
      inited = true;
 }

 function getResult(){
      var a = 1;
      do { a=1; }
      while(!inited);
      //return some variables
 }
person Nicholas    schedule 09.07.2014
comment
timeout няма да работи в моя случай, тъй като разчитам на връщания от функцията на javascript на android. Но благодаря за отговора - person tugce; 10.07.2014

Следният отговор може да помогне в тази и други подобни ситуации като синхронно AJAX повикване -

Работещ пример

waitForMe().then(function(intentsArr){
  console.log('Finally, I can execute!!!');
},
function(err){
  console.log('This is error message.');
})

function waitForMe(){
    // Returns promise
    console.log('Inside waitForMe');
    return new Promise(function(resolve, reject){
        if(true){ // Try changing to 'false'
            setTimeout(function(){
                console.log('waitForMe\'s function succeeded');
                resolve();
            }, 2500);
        }
        else{
            setTimeout(function(){
                console.log('waitForMe\'s else block failed');
                resolve();
            }, 2500);
        }
    });
}
person Sujit Kumar Singh    schedule 01.08.2017