【问题标题】:How to block on asynchronous functions in JavaScript如何在 JavaScript 中阻止异步函数
【发布时间】:2011-05-19 18:12:07
【问题描述】:

我需要用 JavaScript 编写一个函数,它通过调用异步函数返回一个状态。但是,调用者只接收值,不提供回调函数。我试过类似的东西:

function getState() {
    var ret = null;
    asyncCall("request",
        function() { ret = "foo"; } // callback
    );
    while (ret === null)
        ; // block on the asynchronous call
    return ret;
}

但是,循环永远不会结束……

有什么想法吗?谢谢。

【问题讨论】:

  • 为什么要首先阻止异步调用?这样做毫无意义。
  • @Tomolak:因为这是 Firefox 提供的调用,我无法更改。预计最多需要几毫秒,我不想仅仅因为这个而重构我的所有其他代码。
  • 能贴出调用getState()的函数吗?
  • @Tomolak:这里发帖太长了,估计很多地方都会调用。因此,我希望这个函数能够返回一个值。
  • 你有没有得到任何有效的答案?我也面临同样的问题,直到现在找不到任何正确的答案。我现在唯一的选择是在许多地方重构代码以使用异步方法。

标签: javascript asynchronous


【解决方案1】:

为什么不只是:

asyncCall("request", function() {
    // here you can inspect the state
});

包装函数的意义何在?

异步函数以这种方式工作。如果要阻止执行,则使用同步调用:

var state = syncCall("request");

【讨论】:

  • 它有点像图书馆,因为我在多个平台上工作。剩下的代码需要等待这条特殊的信息。不提供同步替换。
  • @Šime:所以你的意思是异步调用会感染所有其他调用它的代码?我只想知道是否有办法阻止这些异步调用。
  • @ryanli:没有办法阻止异步调用,除非您 A:将异步调用重写为同步或 B:重写代码以在异步环境中工作。在 javascript 中,自 1999 年以来,B 被认为是最佳实践。
【解决方案2】:

最好的方法是将您想要调用的逻辑放入回调函数中。你有什么理由做不到吗?

您可以使用setInterval 来检查结果,但这也需要回调函数...

【讨论】:

  • 我正在编写一个扩展,而不是普通的文档 JavaScript。函数的其余部分依赖于这个状态,唯一提供的就是一个异步函数。
【解决方案3】:

您要执行的是同步调用,因此使用专为异步调用设计的函数来执行此操作不是一个好主意。

你在这里有答案:How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

【讨论】:

  • 我知道这一点,但这不是 XHR 请求。
【解决方案4】:

我认为您正在寻找 StratifiedJS,http://stratifiedjs.org 它允许你像你写的那样“编排”你的异步代码,注意它像同步代码一样“写”,它不会阻塞你的应用程序的其余部分。 通过加载 apollo js 库,您可以在任何地方使用它。

这就是它在 Stratified JavaScript 中的样子:

function getState() {
  waitfor (var ret) {
    // block on the asynchronous call
    asyncCall("request", resume);
  }
  return ret;
}

当然有一些模块/库可以使它看起来像这样: http://onilabs.com/modules#http

function getState() {
  return http.get("request");
}

【讨论】:

  • 虽然这依赖于外部解析器,但这似乎是最好的解决方案。
  • 确实如此。但在宏伟的计划中,它不会增加太多开销。
【解决方案5】:

除非我误解了您的问题,否则您可以查看 jQuery 的 ajaxStop() 事件 - http://api.jquery.com/ajaxstop。这会阻塞,直到所有 ajax 调用都完成。这显然需要通过 jQuery 完成所有异步调用。

$(document).ajaxStop(function() {
    // do your "ajax dependent" stuff here
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 2012-03-29
    相关资源
    最近更新 更多