指令用來設置一個新的變量。
語法 set $variable value;
它可以設置在 server、location、if的位置當中
具體配置案例實例:
設置一個監聽端口8081
配置了$name和$age和default_type可以直接將返回值返回到頁面當中
檢驗語法,重新加載
訪問81下的server接口,正好輸出了Tom=18的內容
variable:變量的名稱,該變量名稱要用"$"作為變量的第一個字符,且不 能與Nginx服務器預設的全局變量同名。
value:變量的值,可以是字符串、其他變量或者變量的組合等。
Rewrite常用全局變量
1、$args
變量中存放了請求URL中的請求指令。比如htt p://192.168.200.133:8080?arg1=value1&arg s2=value2中 的"arg1=value1&arg2=value2",功能和 $query_string一樣
$ages的實際使用,在Ngnix當中添加$ages之后
檢驗語法,重載配置
$args啥也沒有輸出,
在端口后添加?sername=JERPY之后,再使用$args之后就輸出了參數了,其中$args的意思與$query_string一樣
常見的全局變量2
$http_user_agent
變量存儲的是用戶訪問服務的代理信息(如果 通過瀏覽器訪問,記錄的是瀏覽器的相關版本 信息)
什么是代理信息,代理信息是用一些工具訪問,如postman,瀏覽器等
配置實例:在conf文件中添加$http_user_agent;參數
檢驗語法,重新加載
$http_user_agent輸出所打印的內容與瀏覽器中Network中的User-Agent打印的內容相同
常見的全局參數之$host
變量存儲的是訪問服務器的server_name值
實際配置,在Ngnix中配置$host文件
檢驗語法,重新加載
$host輸出的內容正好是存儲Ngnix的公網IP
常見的全局參數之$document_uri
它代表的是location后面的內容,輸出也是ngnix中conf配置文件內容中location下面的內容
常見全局參數之$document_root
變量存儲的是當前請求對應location的root 值,如果未設置,默認指向Nginx自帶html目 錄所在位置
之后檢驗語法,重新加載
最后可以看到,它輸出了root下面的文件內容
也可以在日志文件中使用,log_format中設置的main一定要與access_log的main內容相同才可以
之后找到tail -f ../logs/access.log文件
相應的參數打印出來了
開發功能“軌跡播放”時,遇到了一個情況。
原先同事已經開發了一版,這次有個新功能:點擊線上任意一點后可以從點擊處重新播放。
看了一下原來的版本,發現同時使用了setTimeout和setInterval,兩者配合實現點線播放。
簡單結構如下
function test() { setInterval(function () { console.log("interval"); //省略插值方法得到arr (...) play(arr); }, 2000); } function play(arr) { setTimeout(function () { play(arr); console.log("setTimeout"); }, 40); }
我覺得這個結構欠妥,兩個定時器配合必定會出現失誤!因此重構了一版,將兩個定時器改為一個,用setInterval解決。
但是此時我并不知道欠妥欠在什么地方,缺乏理論支持,現在閑下來仔細研究了一下
0|1找問題
在仔細研究了舊版本后,我先把舊版本結構扒了出來,排除其他因素,自己模擬了一個簡單版(就是上面的代碼)
setTimeout:在執行時,是在載入后延遲指定時間后,去執行一次表達式,僅執行一次
setInterval:在執行時,它從載入后,每隔指定的時間就執行一次表達式
從結果得出兩點結論
function test() { setInterval(function () { console.log("interval"); play(); }, 2000); } function play() { //延遲執行 for (var i = 0; i < 100000000; i++) { } setTimeout(function () { play(); console.log("setTimeout"); }, 40); }
從結果得出兩點結論
從結果得出結論
0|1涉及知識點
綜上實驗結果,網上搜集了一些資料能說明問題:
0|1解決方案
在做軌跡播放時,setInterval的延遲還在可接受范圍之內,但是網上給出的最佳解決方案是用setTimeout做。
setTimeout只會執行一次,在執行完成后,重新啟動新的Timeout,時間runtime計算設置為差時,減少出現間隔越來越大的情況
如果寫過js代碼的人對于setTimeout方法一定不會感到陌生。setTimeout是一種定時器,在前端開發中有很多的應用場景,比如在購物車結算成功后,等待幾秒會自動跳轉至列表頁。今天我們就深入的看下setTimeout的實現原理。
Javascript之setTimeout
根據W3C的標準解釋,setTimeout是定義一個在指定時間后觸發的函數。
我們先來看看setTimeout的基本用法,實現這樣一個簡單的效果,點擊一個button,在3秒后頁面上的文字消失。
setTimeout基本用法
由于這段代碼非常基礎,這里不做過多講述。
上面一部分說到setTimeout是相當于給函數定義一個‘鬧鐘’,當到了指定的時間后就會自動執行函數。但是如果我們將時間設置為0,即出現setTimeout(fn, 0)這樣的代碼,情況是怎么樣的呢?是會立即執行嗎?
我們可以通過以下一段代碼來進行測試。
測試代碼
如果和我們猜測的一樣,立即執行的話,上面的測試代碼會按照1 > 2 > 3的順序輸出,但是實際運行后,我們發現輸出結果的順序為1 > 3 > 2,而且不管運行多少次結果都不變。
出現了這樣的結果,就證明了setTimeout(0)并不是立即執行的,那這又該怎么解釋呢?
為了解釋上面這個問題,我們要追溯到JS執行過程,我們都知道JS是單線程執行,所有的異步事件,包括自定義的頁面DOM事件,定時器,Ajax請求都會被添加到一個任務列表按照順序執行。
因為JS腳本文件是運行在瀏覽器端的,我們的JS引擎雖然是單線程的,但是對于瀏覽器來說確是多線程的。瀏覽器中不僅包括JS引擎,還包括網絡請求Ajax,瀏覽器渲染等,它們都有特定的線程去執行。
setTimeout并不能作為多線程使用,可以通過以下一段代碼來證明。
測試代碼
對于以上一段代碼,如果setTimeout可以作為多線程使用,則新的線程會在一秒后將isEnd屬性設置false,那么在一秒后會alert出end字符串。
但是實際情況確是,頁面從未打印出end字符串,而且頁面會呈現鎖死狀態,這是因為isEnd變量值并未修改為false,相當于執行while(true),最終頁面會崩潰。這也就能證明JS引擎是單線程執行狀態。
既然JS引擎是單線程執行,那么setTimeout定義的事件該具體何時觸發呢?
這里我們需要深入到瀏覽器內核設計,在內核中涉及到一個事件隊列的概念,我們可以直接看如下這張圖。
事件隊列
從上面這張圖很容易看出,在瀏覽器內核中包含了各式各樣的線程,有瀏覽器GUI渲染線程,Javascript引擎線程,網絡請求線程。
在當JS引擎執行到其他線程相關的代碼時,就會執行其他線程的代碼,在其他線程執行完畢后需要JS引擎重新運行時,就會在JS引擎的事件隊列里添加一個任務。
現在我們來看看setTimeout(0)做了什么?它會開啟一個定時器線程,并不會影響后續的代碼執行,這個定時器線程會在事件隊列后面添加一個任務,例如上面圖中的t3。等到前面的t1,t2執行完后再去執行t3,因此在前面第二部分內容中的輸出順序為1 > 3 > 2。
既然說到了setTimeout,就不得不提到setInterval,setInterval同樣作為一種定時器,是在指定的時間間隔后執行相應的函數。
一種最常見的場景是頁面上的倒計時實現。這里我們實現一個簡單的效果,指定一個時間,并進行倒計時。
倒計時
setTimeout與setInterval雖然都是定時器,但是在執行上還是有不一樣的。
setTimeout是指定的時間后執行一次;setInterval是在每隔指定的時間后執行多次。
setTimeout(fn1, t1),fn1的執行時間是大于或等于t1的;setInterval(fn2, t2),fn2的執行會始終嘗試在t2時間后執行,如果網絡請求較大的話,會出現fn2連續執行的情況。
今天這篇文章主要講解了Javascript中的setTimeout用法和執行原理,以及與setInterval的簡單比較,大家學會了嗎?
*請認真填寫需求信息,我們會在24小時內與您取得聯系。