【问题标题】:javascript function wait until another function to finishjavascript函数等到另一个函数完成
【发布时间】:2014-08-30 14:34:08
【问题描述】:

我有两个从 android 调用的 javascript 函数。经过长时间的调试会话后,我终于意识到问题出在第二个函数在第一个函数完成之前被调用的事实。我已经用 deferred etc 搜索了这些例子,但它们都依赖于另一个函数调用。

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 实现这一点?

【问题讨论】:

  • 如果尚未翻转,您能否设置一个 isInitialized 标志并在 getResult 中休眠?
  • FunctInit 是否执行一些您也希望等待完成的异步操作?
  • @PaulS。是的,它还调用了两个函数,需要在 getResult 之前完成
  • 您可能想阅读有关“回调”的内容。例如:recurial.com/programming/… 这很难理解,但功能强大,当然是解决您问题的好方法。
  • 我希望你把答案记下来,所以我不想在那里发帖看到这里stackoverflow.com/questions/12116505/…

标签: javascript jquery callback jquery-deferred


【解决方案1】:

在我看来,延迟/承诺(正如您所提到的)是要走的路,而不是使用超时。

这是我刚刚写的example,用于演示如何使用延迟/承诺来做到这一点。

花一些时间来玩弄延迟。一旦你真正理解了它们,执行异步任务就变得非常容易了。

希望这会有所帮助!

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

【讨论】:

  • 为什么将函数包装在$.when() 中?没有必要。你可以只做function1().done() - 根本不需要$.when()$.when() 用于当您有多个 Promise 并且您想知道它们何时全部完成时使用,但仅传递一个 Promise 时根本没有用处。
  • 你说的很对,一开始我有多个承诺,我只是忘了删除$.when。在您发表评论的同时,我几乎注意到了这一点。感谢您指出!
  • 非常感谢您提供的示例。通过一个简单的例子来解释是一个很好的方法@AntoineCloutier
  • 很抱歉我不太了解它是如何工作的,所以我只是按照示例进行操作。当我使用 .done 调用函数时,出现错误“无法读取未定义的属性‘完成’”。
  • 嗨@AntoineCloutier 我不太了解延迟,但只想知道为什么您仍然使用超时而不是仅使用延迟?
【解决方案2】:

我可以想到几种方法来做到这一点。

使用回调:

 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
 }

【讨论】:

  • timeout 在我的情况下不起作用,因为我依赖于 android 上 javascript 函数的返回。但是,谢谢你的回答
【解决方案3】:

以下答案可以帮助解决这种情况和其他类似情况,例如同步 AJAX 调用 -

工作example

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

【讨论】:

    猜你喜欢
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多