JavaScript 引擎有多個執行緒,單個腳本只能在主執行緒運行,其他執行緒都在后臺配合.
單執行緒模型雖然對 JavaScript 構成了很大的限制,但也因此使它具備了其他語言不具備的優勢,如果用得好,JavaScript 程式是不會出現堵塞的,這就是為什么 Node 可以用很少的資源,應付大流量訪問的原因,
目錄
一.定時器
setTimeout(JavaScript函式/要執行的代碼, 等待的毫秒數)
clearTimeout(timeoutID)
setInterval(JavaScript函式/要執行的代碼, 等待的毫秒數)
二.幾種模式
1.回呼函式
2.事件監聽
3.發布/訂閱
三.流程控制
1.串行執行(一個任務完成以后,再執行另一個)
2.并行執行(所有異步任務同時執行,等到全部完成以后,才執行)
3.串并結合(設定一個門檻,每次最多只能并行執行n個異步任務)
一.定時器
setTimeout(JavaScript函式/要執行的代碼, 等待的毫秒數)
(三秒后會出現一個"ABC"的按鈕)
<p id="content"> 請等三秒鐘!</p>
<script>
setTimeout("changeState()",3000 );
function changeState(){
var content=document.getElementById('content');
content.innerHTML="<input type='button' value='ABC'>";
}
</script>
(一個計時器)
<input type="button" id="displayBox" value="0">
<script>
x = 0
function countSecond()
{
x = x+1
document.getElementById("displayBox").value=x
setTimeout("countSecond()", 1000)
}
countSecond()
</script>
clearTimeout(timeoutID)
timeoutID 為呼叫 setTimeout() 函式時所獲得的回傳值,使用該回傳識別符號作為引數,可以取消該 setTimeout() 所設定的定時執行操作

<form class="countNum">
<input type="text" id="addNum" value="0" size="4" >
<input type="button" value="開始" onclick="countNum()">
<input type="button" value="停止" onclick="clearTimeout(matter)">
</form>
<script>
x = 0
function countNum(){
document.getElementById('addNum').value=x;
x += 1
matter=setTimeout("countNum()",1000)
}
function stopNum(){
}
</script>
setInterval(JavaScript函式/要執行的代碼, 等待的毫秒數)
一個時鐘
<p id="timer"></p>
<script>
setInterval("myTimer()",1000)
function myTimer(){
var d=new Date();
var t=d.toLocaleTimeString();
document.getElementById('timer').innerHTML = t
}
</script>
二.幾種模式
1.回呼函式
| 優點 | 缺點 |
| 簡單、容易理解和實作 | 各個部分之間高度耦合,使得程式結構混亂、流程難以追蹤(尤其是多個回呼函式嵌套的情況),而且每個任務只能指定一個回呼函式 |
function f1(callback) {
// ...
callback();
}
function f2() {
// ...
}
f1(f2);
2.事件監聽
| 優點 | 缺點 |
| 容易理解,,有利于實作模塊化 | 整個程式都要變成事件驅動型,運行流程會變得很不清晰, 難以分辨出主流程 |
f1.on('done', f2);
function f1() {
setTimeout(function () {
// ...
f1.trigger('done');
}, 1000);
}
f1.trigger('done')表示,執行完成后,立即觸發done事件,從而開始執行f2
3.發布/訂閱
| 與“事件監聽”類似,但是優于后者,因為可以通過查看“訊息中心”,了解存在多少信號、每個信號有多少訂閱者,從而監控程式的運行 |
f2向信號中心jQuery訂閱done信號
jQuery.subscribe('done', f2);
function f1() {
setTimeout(function () {
// ...
jQuery.publish('done');
}, 1000);
}
f1執行完成后,向信號中心jQuery發布done信號,從而引發f2
f2完成執行后,可以取消訂閱
jQuery.unsubscribe('done', f2);
三.流程控制
1.串行執行(一個任務完成以后,再執行另一個)
在下面的例子,goals陣串列示每一個異步任務的引數,results陣列保存每一個異步任務的運行結果, Series就是串行函式,它會依次執行異中步任務,所有任務都完成后,才會執行Final函式,
var goals = [1, 2, 3, 4, 5, 7];
var results = [];
function ShowStep(num, callback){
console.log('引數為 ' + num +' , 1秒后回傳結果');
setTimeout(function(){ callback(num*2); }, 1000);
}
function Final(valueFinal){
console.log('完成, 最后的生成值為: ', valueFinal);
}
function Series(goal){
if(goal){
ShowStep(goal, function(result){
results.push(result);
return Series(goals.shift());
});
}else{
return Final(results[results.length-1]);
}
}
Series(goals.shift());
輸出 : 
2.并行執行(所有異步任務同時執行,等到全部完成以后,才執行)
var goals = [ 1, 2, 3, 4, 5, 7 ];
var results = [];
function ShowStep(num, callback) {
console.log('引數為 ' + num +' , 1秒后回傳結果');
setTimeout(function () { callback(num * 2); }, 1000);
}
function Final(valueFinal) {
console.log('完成,最后的生成值為: ', valueFinal);
}
goals.forEach(function(item) {
ShowStep(item, function(result){
results.push(result);
if(results.length === goals.length) {
Final(results[results.length - 1]);
}
})
});
forEach方法會同時發起六個異步任務,等到它們全部完成以后,才會執行Final函式 .
這次用時變為上面的六分之一(僅需一秒就能完成整個腳本),問題在于如果并行的任務較多,很容易耗盡系統資源,拖慢運行速度, 因此有了二者結合的流程控制方式👇👇👇
3.串并結合(設定一個門檻,每次最多只能并行執行n個異步任務)
避免過分占用系統資源
var goals = [ 1, 2, 3, 4, 5, 7 ];
var results = [];
var running = 0;
var limit = 2;
function async(num, callback) {
console.log('引數為 ' + num +' , 1秒后回傳結果');
setTimeout(function () { callback(num * 2); }, 1000);
}
function Final(valueFinal) {
console.log('完成:,最后的生成值為: ', valueFinal);
}
function launcher() {
while(running < limit && goals.length > 0) {
var item = goals.shift();
async(item, function(result) {
results.push(result);
running--;
if(goals.length > 0) {
launcher();
} else if(running == 0) {
Final(results);
}
});
running++;
}
}
launcher();
(兩個兩個進行)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293752.html
標籤:其他
下一篇:vue中呼叫百度地圖 獲取經緯度
