2

我知道这个问题已经以许多不同的方式被问过很多次,但我仍然无法确定以下问题的良好解决方案。

在从外部函数返回之前,如何等待这个异步执行的内部函数的回调完成?

function outer() {
    var result = false;
    var innerAsynch = function() {
        result = true;
    }
    setTimeout(innerAsynch, 1000);
    waitForInnerAsynch(); //blocking
    return result;  //true
}

1) 我很清楚这对 99.999% 的用例来说是不好的做法,所以请不要告诉我不应该这样做!

2)请随意完全重构这段代码......我唯一的要求是outer()返回的东西会阻止浏览器,直到innerAsynch()完成并通过以下测试:

 if(outer()) {
    //1 second later.... yippee!
 }

我也在使用 jQuery,但我宁愿不使用插件,除非这样做真的很有意义。谢谢!

更新

我想重申一下,我的目标是将异步执行完全封装在对 external() 的同步调用中,不带参数。

换句话说,这应该有效:

<a href="something" onclick="return outer()">A very slow link</a>

也许这实际上是不可能的,在这种情况下我可以使用回调,但我想更好地理解为什么会这样。

4

2 回答 2

1

我想重申一下,我的目标是将异步执行完全封装在对 external() 的同步调用中,不带参数。

存在异步执行和回调的唯一原因是不阻塞。如果您真的想阻止,请不要使用异步代码。如果您确实依赖异步函数,请重新构建代码以使用回调。就这么简单。

JavaScript 是单线程的,因此,如果您阻塞,浏览器似乎会冻结,直到您的代码解除阻塞。当您阻止时,您甚至无法更新 UI 以通知用户正在执行某些长时间运行的操作。这就是为什么它很糟糕。请记住,该语言是围绕事件循环和异步事件队列设计的;试图违背这一点只会导致头疼。

于 2012-11-12T18:51:44.430 回答
1

标准 js 模式。您只需要使用回调:

function outer(callback) 
{
    var innerAsynch = function(innerCallback) {
        var result = true;
        innerCallback(result);
    }

    setTimeout(function()
    {
      innerAsynch(function(result)
      {
        callback(result);
      });

    }, 1000);
}

用法:

outer(function(result)
{
  if ( result )
    //true
  else
    //false
});
于 2012-11-12T17:55:15.270 回答