自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一道面試題引發(fā)的面壁:認識JavaScript的settimeout和異步

開發(fā) 前端
今晚看到QLeelulu的一道JavaScript面試題(setTimeout),稍微想了一下,好不容易連猜帶蒙,湊巧說對了答案。但是原因到底是什么呢?自己一時也說不太清楚,反正感覺就是一個死循環(huán)造成的。那么我們就回到原點重新認識javascript的settimeout和異步吧!

一道JavaScript面試題(setTimeout)

下面的代碼,多久之后會彈出'end'? 為什么?

這是以前在想有沒辦法實現(xiàn)阻塞javascript線程的時候(即實

  1. var t = true;  
  2.  
  3. setTimeout(function(){ t = false; }, 1000);  
  4.  
  5. while(t){ }  
  6.  
  7. alert('end'); 

現(xiàn)sleep方法),想過的一種實現(xiàn)。

很簡單,是吧?

是嗎?

重新認識javascript的settimeout和異步

今晚看到QLeelulu的一道JavaScript面試題(setTimeout),稍微想了一下,好不容易連猜帶蒙,湊巧說對了答案。但是原因到底是什么呢?自己一時也說不太清楚,反正感覺就是一個死循環(huán)造成的。然后看了一下文章下面的評論,發(fā)現(xiàn)5樓(典型的死循環(huán)……js是單線程執(zhí)行的,while里面死掉的時候setTimeout里面的函數是沒機會執(zhí)行的。)和6樓(setTimeout 只是掛了個定時任務,但是 JS 本身是單線程的,while 那里肯定死掉了。)的回答很有道理,主要意思就是說javascript引擎是單線程執(zhí)行的,while循環(huán)那里執(zhí)行的時候,settimeout里面的函數根本沒有執(zhí)行的機會,這樣while那里永遠為真,造成死循環(huán)。但是單純看還是不怎么踏實,最后發(fā)揮實踐精神,自己動手做了兩個實驗:

1、簡單的settimeout

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

執(zhí)行的結果是彈出‘end’‘end 1’,然后瀏覽器假死,就是不彈出‘end 2’。也就是說第一個settimeout里執(zhí)行的時候是一個死循環(huán),這個直接導致了理論上比它晚一秒執(zhí)行的第二個settimeout里的函數被阻塞,這個和我們平時所理解的異步函數多線程互不干擾是不符的。

2、ajax請求回調

接著我們來測試一下通過xmlhttprequest實現(xiàn)ajax異步請求調用,主要代碼如下:

  1. var xmlReq = createXMLHTTP();//創(chuàng)建一個xmlhttprequest對象  
  2.        function testAsynRequest() {  
  3.            var url = "/AsyncHandler.ashx?action=ajax";  
  4.            xmlReq.open("post", url, true);  
  5.            xmlReq.setRequestHeader("Content-Type""application/x-www-form-urlencoded");  
  6.            xmlReq.onreadystatechange = function () {  
  7.                if (xmlReq.readyState == 4) {  
  8.                    if (xmlReq.status == 200) {  
  9.                        var jsonData = eval('(' + xmlReq.responseText + ')');  
  10.                        alert(jsonData.message);  
  11.                    }  
  12.                    else if (xmlReq.status == 404) {  
  13.                        alert("Requested URL is not found.");  
  14.                    } else if (xmlReq.status == 403) {  
  15.                        alert("Access denied.");  
  16.                    } else {  
  17.                        alert("status is " + xmlReq.status);  
  18.                    }  
  19.                }  
  20.            };  
  21.            xmlReq.send(null);  
  22.        }  
  23.        testAsynRequest();//1秒后調用回調函數  
  24.          
  25.        while (true) {  
  26.  
  27.        } 

在服務端實現(xiàn)簡單的輸出:

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

理論上,如果ajax異步請求,它的異步回調函數是在單獨一個線程中,那么回調函數必然不被其他線程”阻撓“而順利執(zhí)行,也就是1秒后,它回調執(zhí)行彈出‘ajax’,可是實際情況并非如此,回調函數無法執(zhí)行,因為瀏覽器再次因為死循環(huán)假死。

結論:根據實踐結果,可以得出,javascript引擎確實是單線程處理它的任務隊列(能理解成就是普通函數和回調函數構成的隊列嗎?)的。在javascript里實現(xiàn)異步編程很大程度上就是一種障眼法,單線程的引擎實現(xiàn)多線程的編程,如果要實現(xiàn)一些資源同步互斥之類的操作(一如C#、Java等語言的多線程),我感覺真正實現(xiàn)起來根本無法輕易得到保證。

補充:如何實現(xiàn)javascript的sleep呢?在stackoverflow上找到一篇javascript sleep,試了一下,效果是有了,但是執(zhí)行的時候cpu很高,真還不如直接settimeout呢。

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

【編輯推薦】

  1. JavaScript重構深入剖析
  2. 19個很有用的JavaScript庫強烈推薦
  3. 驚動大神的JavaScript:在Web上運行Linux
  4. 15款超棒的JavaScript開發(fā)工具推薦
  5. 從零開始學習jQuery之你必須知道的JavaScript
責任編輯:陳貽新 來源: Jeff Wong的博客
相關推薦

2017-03-10 09:33:16

JavaScript類型

2021-03-16 05:44:26

JVM面試題運行時數據

2015-09-02 14:09:19

面試題程序設計

2024-10-11 17:09:27

2018-03-06 15:30:47

Java面試題

2011-05-23 11:27:32

面試題面試java

2021-05-31 07:55:44

smartRepeatJavaScript函數

2023-02-04 18:24:10

SeataJava業(yè)務

2009-08-11 10:12:07

C#算法

2009-08-11 14:59:57

一道面試題C#算法

2009-08-11 15:09:44

一道面試題C#算法

2017-11-21 12:15:27

數據庫面試題SQL

2022-04-08 07:52:17

CSS面試題HTML

2024-06-04 14:52:28

2021-10-28 11:40:58

回文鏈表面試題數據結構

2023-08-01 08:10:46

內存緩存

2011-03-02 10:58:16

SQL server入門面試題

2017-09-13 07:15:10

Python讀寫文件函數

2021-03-27 10:59:45

JavaScript開發(fā)代碼

2022-02-08 18:09:20

JS引擎解析器
點贊
收藏

51CTO技術棧公眾號