nodejs異步編程,重新認識javascript的settimeout和異步

 2023-10-30 阅读 29 评论 0

摘要:今晚看到QLeelulu的一道JavaScript面試題(setTimeout),稍微想了一下,好不容易連猜帶蒙,湊巧說對了答案。但是原因到底是什么呢?自己一時也說不太清楚,反正感覺就是一個死循環造成的。nodejs異步編程?然后看了一下文章下面

今晚看到QLeelulu的一道JavaScript面試題(setTimeout),稍微想了一下,好不容易連猜帶蒙,湊巧說對了答案。但是原因到底是什么呢?自己一時也說不太清楚,反正感覺就是一個死循環造成的。nodejs異步編程?然后看了一下文章下面的評論,發現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’。javascript,也就是說第一個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,如需轉載請自行聯系原作者

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/165309.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息