繁体   English   中英

JavaScript 异步/等待逻辑表现为同步

[英]JavaScript Async/Await logic behaving as synchronous

如果我理解正确,用关键字async声明的 function 应该返回 promise。在async3 function 的情况下,我们有 10 亿次迭代,这使得返回值需要更长的时间。 分析下面的代码,我预计会发生的事情是,通过调用sync1sync2 function,立即登录控制台,稍后,async3 function 日志会出现。 但是,我注意到sync1sync2函数仅在async3结束后才记录。 async3 function难道不应该在另一个线程上或事件循环之外运行,而不会阻止在运行时调用的其他函数的执行吗?

 function sync1() { console.log(1); } function sync2() { console.log(2); } async function async3() { let iteration = 0; let number = 0; while (iteration <= 1000000000) { number = iteration; iteration++; } return number; } sync1(); sync2(); async3().then((val) => console.log(val));

你能解释一下为什么它会这样吗? 我错过了什么?

我期望的是:

sync1(); // console logged immediately
sync2(); // console logged immediately
async3().then((val) => console.log(val)); // console logged moments later

目前正在发生的事情:


     sync1(); // console logged after async3 is done 
     sync2(); // console logged after async3 is done
     async3().then((val) => console.log(val)); // console logged after async3 is done

请记住 JavaScript 基本上是单线程的。

尽管async3是异步的,但它的操作完全是同步的,并且是 CPU 密集型的。 一旦浏览器有一点空闲时间,output 只会(视觉上)打印到控制台,但以下块:

  while (iteration <= 1000000000) {
    number = iteration;
    iteration++;
  }

在完成上述计算之前,不会让浏览器有空闲时间。

对于sync1sync2立即记录,一种解决方案是让async3每 100,000 次迭代(或其他)暂停,并等待setTimeout ,从而让浏览器有机会做一些事情,比如向控制台显示内容,处理其他事件监听器,渲染变化,等等。

另一种解决方案是在worker中执行计算量大的async3 function,它位于单独的线程上,不会阻塞浏览器的主线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM