• 重新认识javascript的settimeout和异步


    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呢。

    原文:http://www.cnblogs.com/jeffwongishandsome/archive/2011/06/13/2080145.html

  • 相关阅读:
    第一轮冲刺团队评分
    意见汇总
    各组对我组的评价
    对各项目评价建议
    【每日Scrum】第十天冲刺
    【每日Scrum】第九天冲刺
    SQL-插入的方法
    Random
    基本测试理论
    web项目工作流程
  • 原文地址:https://www.cnblogs.com/yanglang/p/7090290.html
Copyright © 2020-2023  润新知