【问题标题】:Why Can't Javascript Functions be Blocking? [closed]为什么 Javascript 函数不能阻塞? [关闭]
【发布时间】:2017-03-10 16:00:39
【问题描述】:

一些观察。 某些原生 javascript 函数被阻塞。比如警告框。如果浏览器允许用户编写其他阻止功能,它们的恶意可能不亚于破坏自己的页面。所以我不认为这是一个安全问题。

启用阻塞功能可能会引入不良的设计模式。也许目标只是阻止草率的设计,因为 javascript 绝对是异步的。但这是一个相当固执己见的设计理念,要构建到语言本身中。

问题: 是否有任何历史或技术原因导致无法构建另一个功能?或者反过来说,我是不是搞错了,有什么办法可以让其他功能阻塞吗?

建议的设计模式。我认为值得展示我所说的阻塞函数的含义。正常的设计模式是这样做的:

doSomethingThatMayTakeTime();
function doSomethingThatMayTakeTime(){
     //Something that takes time
     callback();
}

function callback(){
    //Do something you only want to do once the first function is complete
}

但在我的代码中有很多地方,在执行 doSomethingThatMayTakeTime 函数之前,我希望执行 没有可能的代码。在这种使用场景下,我们为什么可以说:

doSomethingThatMayTakeTime();
//NextLineOfCode

function doSomethingThatMayTakeTime(){
     // Blocking Code -- Prevent execution of any code outside this function until this function returns/executes its last line
     //Something that takes time
}

正如您在这个特定用例中看到的那样,认为这是一种更清洁的方法并不会发疯。虽然这看起来很具体,但我相对经常遇到这种情况。一个简单的例子是用其他模态框替换警告框。

【问题讨论】:

  • “没有我想要执行的代码”。你的代码 - 也许。但是浏览器同时运行了很多其他的 JS。您的代码必须发挥出色。
  • What topics can I ask about here?: "但如果您的问题一般涉及特定的编程问题,或者软件算法,或者程序员常用的软件工具;并且是软件开发独有的实用且可回答的问题,那么您来对地方提出问题了!" ;)
  • FWIW,alert 不是 JavaScript/ECMAScript 的一部分。它是浏览器提供的 API(它可以做任何它想做的事情)。然而,ECMAScript 也没有明确地“禁止”阻塞函数。除了 Promises,它实际上并没有指定异步函数。 浏览器提供异步API函数(根据HTML标准)。
  • 每一个引用都是断章取义的。这并不意味着它不适用。例如,Help Center 相当明确地说明了不应该问的问题:“你应该只根据你所面临的实际问题提出实用的、可回答的问题。喋喋不休、开放式的问题会降低我们网站的实用性并推动头版上的其他问题。” (哦,您对 Andreas 引述的“上下文”的引用不完整;您省略的“...”以 “一个特定的编程问题”开头/i>。您的帖子与任何类别都不匹配。)
  • 一点历史,请阅读:stackoverflow.com/questions/29883525/…(向下滚动到我描述事件循环的部分)。然后阅读这篇文章,了解为什么保持这种方式是个好主意:stackoverflow.com/questions/29981941/…。这也说明了它最终如何成为服务器上的一种高性能编程风格:stackoverflow.com/questions/34855352/…

标签: javascript asynchronous


【解决方案1】:

有没有办法让其他功能阻塞?

函数本身,所有都是阻塞的。放入一个无限循环并观察您的浏览器挂起。

I/O 是异步的。不要混淆两者。

【讨论】:

  • 我不确定我是否遵循。能否详细说明一下。
  • I/O,输入/输出 - 访问外部资源。进行ajax调用,下载文件,诸如此类。在 node.js 中这还包括数据库访问、读取文件等。
【解决方案2】:

你的意思是这样的吗?任何长时间执行任何操作的函数都会冻结您的浏览器(在完成之前没有事件处理),我认为您不了解 Javascript 的单线程行为:

$('#blocking').click(function() {
  var d= new Date().getTime();
  while(new Date().getTime() - d < 10000) {
    var a=1;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="blocking">Block this tab for 10 seconds</button>

【讨论】:

    【解决方案3】:

    当您运行阻止功能时,被阻止的不仅仅是页面上的代码。它是整个 JavaScript 引擎的主线程。如果用户单击按钮、尝试在输入字段中键入内容、滚动页面或执行任何生成 JS 引擎应该处理的事件的操作,则在阻塞函数返回之前不会发生任何事情。

    这是一件坏事。对用户来说,这与浏览器崩溃没有区别。

    请注意,警报框不会以相同的方式阻止。是的,主事件处理线程被阻塞,但不是所有事件处理。对话框接管所有事件处理并以响应方式对其进行处理。可以这样想:弹出警报暂时改变什么被认为是事件;它根本不会阻止事件。

    你说,“javascript 绝对是异步的”。我不知道你的意思是什么,但作为一个笼统的陈述,这绝对是不真实的。 (例如,参见this thread。)您需要付出特别的努力来创建异步活动。请参阅this documentation 了解更多信息。

    【讨论】:

      猜你喜欢
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      • 2013-02-20
      • 2012-10-19
      • 1970-01-01
      • 2020-12-07
      • 2020-03-29
      相关资源
      最近更新 更多