今晚看到QLeelulu的一道JavaScript面试题(setTimeout),稍微想了一下,好不容易连猜带蒙,凑巧说对了答案。但是原因到底是什么呢?自己一时也说不太清楚,反正感觉就是一个死循环造成的。然后看了一下文章下面的评论,发现5楼和6楼的回答很有道理,主要意思就是说javascript引擎是单线程执行的,while循环那里执行的时候,settimeout里面的函数根本没有执行的机会,这样while那里永远为真,造成死循环。但是单纯看还是不怎么踏实,最后发挥实践精神,自己动手做了两个实验:

1、简单的settimeout

        setTimeout(function () { while (true) { } }, 1000);setTimeout(function () { alert('end 2'); }, 2000);setTimeout(function () { alert('end 1'); }, 100);alert('end');

执行的结果是弹出‘end’‘end 1’,然后浏览器假死,就是不弹出‘end 2’。也就是说第一个settimeout里执行的时候是一个死循环,这个直接导致了理论上比它晚一秒执行的第二个settimeout里的函数被阻塞,这个和我们平时所理解的异步函数多线程互不干扰是不符的。

2、ajax请求回调

接着我们来测试一下通过xmlhttprequest实现ajax异步请求调用,主要代码如下:

        var xmlReq = createXMLHTTP();//创建一个xmlhttprequest对象function testAsynRequest() {var url = "/AsyncHandler.ashx?action=ajax";xmlReq.open("post", url, true);xmlReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xmlReq.onreadystatechange = function () {if (xmlReq.readyState == 4) {if (xmlReq.status == 200) {var jsonData = eval('(' + xmlReq.responseText + ')');alert(jsonData.message);}else if (xmlReq.status == 404) {alert("Requested URL is not found.");} else if (xmlReq.status == 403) {alert("Access denied.");} else {alert("status is " + xmlReq.status);}}};xmlReq.send(null);}testAsynRequest();//1秒后调用回调函数while (true) {}

在服务端实现简单的输出:

        private void ProcessAjaxRequest(HttpContext context){string action = context.Request["ajax"];Thread.Sleep(1000);//等1秒string jsonObject = "{\"message\":\"" + action + "\"}";context.Response.Write(jsonObject);}

理论上,如果ajax异步请求,它的异步回调函数是在单独一个线程中,那么回调函数必然不被其他线程”阻挠“而顺利执行,也就是1秒后,它回调执行弹出‘ajax’,可是实际情况并非如此,回调函数无法执行,因为浏览器再次因为死循环假死。

结论:根据实践结果,可以得出,javascript引擎确实是单线程处理它的任务队列(能理解成就是普通函数和回调函数构成的队列吗?)的。在javascript里实现异步编程很大程度上就是一种障眼法,单线程的引擎实现多线程的编程,如果要实现一些资源同步互斥之类的操作(一如C#、Java等语言的多线程),我感觉真正实现起来根本无法轻易得到保证。

补充:如何实现javascript的sleep呢?在stackoverflow上找到一篇javascript sleep,试了一下,效果是有了,但是执行的时候cpu很高,真还不如直接settimeout呢。

本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2011/06/13/2080145.html,如需转载请自行联系原作者

重新认识javascript的settimeout和异步相关推荐

  1. C# Task 循环任务_聊聊 JavaScript 的并发、异步和事件循环

    本文作者:Cody Chan,题图来自 Jake Archibald JavaScript 作为天生的单线程语言,社区经常聊 JavaScript 就聊异步.聊 Event Loop,看起来它们好像难 ...

  2. JavaScript 循环中调用异步函数的三种方法,及为什么 forEach 无法工作的分析

    JavaScript 循环中调用异步函数的三种方法,及为什么 forEach 无法工作的分析 业务分析 初版的问题 解决方案 传统的 for 循环 不使用 for 循环的解决方案 分析 forEach ...

  3. javascript 权威指南第7版_第七版 JavaScript 权威指南之异步

    一些计算程序,比如科学模拟和机器学习模型,是计算密集型[compute-bound]的.它们不间断地运行直到得到结果. 大多数现实世界的程序,则是异步的.浏览器里的 JavaScript 程序是典型的 ...

  4. [转]掌握Ajax 第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 [IBM]

    转自:http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步 ...

  5. javascript中setTimeout()函数

    javascript中setTimeout()函数 大家都知道javascript中的setTimeput()函数的作用,一般会用他来处理一些连续的事情,们先看一个例子: <head>   ...

  6. 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求

    转http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 ...

  7. AJAX工作原理及其优缺点 1.什么是AJAX? AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页

    参考文章:https://www.cnblogs.com/SanMaoSpace/archive/2013/06/15/3137180.html AJAX工作原理及其优缺点 1.什么是AJAX? AJ ...

  8. JavaScript———从setTimeout与setInterval到AJAX异步

    setTimeout与setInterval执行 首先我们看一下以下代码打印结果 1 2 3 4 5 6 7 console.log(1); setTimeout(function() { conso ...

  9. JavaScript单线程 setTimeout定时器

    理解JavaScript的单线程的理念对于JavaScript学习,以及掌握其中的一些设计机制非常重要,比如回调.定时器.对于后续学习NodeJS也有很大的帮助. 通过先demo,后总结的形式,使得J ...

最新文章

  1. mysql 关联关系
  2. Oracle发布开源的轻量级 Java 微服务框架 Helidon 1
  3. filebeat+elk简单搭配
  4. 19年8月 字母哥 第二章 RESTFul接口实现与测试 看到这里了
  5. 设备驱动,字符设备驱动、(总线)设备驱动模型、sysfs文件系统、平台设备驱动
  6. mysql怎么拆字符串_MySQL截取和拆分字符串函数用法示例
  7. SpringBoot应用部署[转]
  8. Linux系统中用stat命令查看文件的三个时间属性
  9. Java中使用poi导入、导出Excel
  10. 阿里云推出企业级智能协同办公方案 云桌面、云AP、云客服一应俱全
  11. python缩进格式错误修改_Python,意外的缩进错误解析,Pythonunexpectedindent,解决,方法...
  12. linux的make命令是什么,Linux中make, make install命令分别是什么
  13. 10、斐波那契数列,跳台阶问题(Python)
  14. GitHub客户端上传本地代码
  15. 717 1比特与2比特字符
  16. 此更新不适用您的计算机 win10,高手亲自讲解Win10系统提示此更新不适用于您的详尽处理办法...
  17. Ubuntu 20.04 实现Windows 复制粘贴
  18. Python金融数据挖掘 第八章 第1节 Apriori算法原理(2)
  19. pycharm 第三方库加载不出来
  20. 仪器仪表应用,国产IC用于替代AD7792,AD7793的型号分享,完全P=P

热门文章

  1. 李笑来登GitHub趋势榜第一,教你自学编程,含37%“硬核鸡汤”
  2. 终于出手!谷歌母公司旗下GV风投首次投资AI芯片创业公司
  3. 为了不把黑人兄弟认作大猩猩,谷歌的算法连真的大猩猩都不认识了
  4. thymeleaf路径问题
  5. mysql修改密码、找回密码
  6. 使用CompletionService结合ExecutorService批处理任务
  7. android-tv
  8. J2EE远程调试,远程debug你的线上Springboot项目
  9. Domino下启用SMTP验证及创建允许匿名验证
  10. freemarker开发指南