17

我想在页面上分开线程以防止 gui 冻结。为此,我正在运行该函数,该函数将使用 setTimeout 将 gui 冻结在另一个线程中,但仍会冻结。

代码和jsbin链接如下:

<!DOCTYPE html>
<html>
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"
  type="text/javascript"></script>
  <meta charset="utf-8" />
</head>
<body>
  <div id="div1"></div>
  <div id="div2"></div>
  <input type="button" value="düðme" id="btn" />

  <script type="text/javascript">
      $("#btn").on("click",function(){
        $("#div1").html(new Date());
      });

      $(document).ready(function(){
        setTimeout(function() { count(); },1);
      });

      function count(){
        for(var i =0;i<100000;i++){
          $("#div2").html(i);
        }
          $("#div2").append(new Date());
      }
  </script>

</body>
</html>
4

4 回答 4

12

即使您通过setTimeout它委托执行仍将在同一个线程中执行,它只会等待其在队列中的时间,并将推迟任何其他活动,直到它完成。

请参考“JS Ninja 的秘密”一书中的这张很棒的图片:

在此处输入图像描述

于 2013-07-12T11:04:26.060 回答
7

Javascript不是多线程的,你可以看看Web Workers

于 2013-07-12T11:02:16.690 回答
6

javascript(browser) 是一个单线程应用程序,因此即使您在任何时间点使用 setTimeout,也只会有一个线程在运行(执行脚本、重新绘制 UI 等)。在此处阅读有关计时器如何工作的更多信息

由于您每毫秒都有一个脚本运行,因此它将冻结线程从而阻塞 UI

于 2013-07-12T11:01:51.823 回答
0

您可以使用“Promise”来操作异步函数:

承诺文件

Promise 是在创建 Promise 时不一定知道的值的代理。它允许您将处理程序与异步操作的最终成功值或失败原因相关联。这让异步方法可以像同步方法一样返回值:异步方法不是立即返回最终值,而是返回一个承诺,以便在未来某个时间点提供该值。

第1步:

const dosomethingPromise = (data, otherInput) => {
return new Promise((resolve, reject) => {
     /* do your work here*/
    resolve(true) /* return result here or you can use reject for execute catch block*/
})

};

第 2 步: 在您的代码中像这样使用它:

 Promise.resolve(dosomethingPromise(data,otherInput))
        .then((result) => {
            /*your result come here*/
            console.log("Progress finished=>", result);
        }, (error) => {
            console.log(error)
        })
        .catch(console.log);

您还可以使用Promise和“all”方法而不是“resolve”方法连续执行多个任务并获得最终结果。

于 2021-01-03T07:48:41.360 回答