JS之異步概念

概念 什麼是JS異步ajax

異步加載也叫非阻塞模式加載,瀏覽器在下載js的同時,還會執行後續的頁面處理.編程

什麼時候須要異步瀏覽器

1 須要等待的狀況網絡

2 在等待過程當中不能像alert同樣阻塞程序運行app

3 等待的狀況須要異步異步

使用場景:函數

1 定時任務setTimeout, setIntervalspa

console.log(100);
 setTimeout(function(){
   console.log(200);
 },1000); //異步執行,非阻塞並不妨礙後續代碼執行
 console.log(300);
//執行順序爲100 300 200

2   網絡請求 ajax 動態<img> 加載線程

console.log("start");
 var img=document.createElement("img");
 img.onload=function(){
   console.log("loaded");
 }
 img.src="https://ps.ssl.qhimg.com/sdmt/75_135_100/t01525fd8d9773b149f.jpg";
 document.body.append(img);
 console.log("end");
 //執行順序是 start end loaded 圖片的加載時異步的

3  事件綁定code

console.log("start");
 document.getElementById("btn").addEventListener("click",function(){
   console.log("clicked");
 });
 console.log("end");
 //執行順序是start ,end 若是點擊才執行clicked 若是不點永遠不執行 也是異步的

典型的同步加載的例子:

console.log(100);
 alert(200);
 console.log(300);
 //同步打印100,彈出200,打印300,取決於按下‘肯定’框的時間,不按就一直卡頓在那

同步或非同步,代表着是否須要將整個流程按順序地完成

阻塞或非阻塞,意味着你調用的函數會不會馬上告訴你結果

2、在js中的阻塞與同異步

你有一個函數和一段程序。

2.1 js中的同步阻塞

// 這是一個阻塞式函數, 將一個文件複製到另外一個文件上
function copyBigFile(afile, bfile){
    var result = copyFileSync(afile,bfile);
    return result;
}

調用這個」copyBigFile()」函數,將一個大文件複製到另外一個文件上,將耗時1小時。意味着這個函數的將在一個小時以後返回。

//這是一段程序
console.log("start copying ... ");    
var a = copyBigFile('A.txt', 'B.txt');  //這行程序將耗時1小時
console.log("Finished");   // 這行程序將在一小時後執行
console.log("處理一下別的事情");  // 這行程序將在一小時後執行
console.log("Hello World, 整個程序已加載完畢,請享用"); // 這行程序將在一小時後執行

以上的程序就是一個同步阻塞的例子,由於copyFileSync函數返回值的過程須要漫長的時間,因此線程也沒法繼續執行下去,只能等待。

2.2 js中的同步非阻塞

// 這是一個非阻塞式函數
// 若是複製已完成,則返回 true, 若是未完成則返回 false
function copyBigFile(afile,bfile){
    var copying = copyFileAsync(afile, bfile);
    var isFinished = !copying;
    return !isFinished; 
}

調用這個函數將馬上返回結果,而後你的程序就能夠寫成

console.log("start copying ... ");    
while( a = copyBigFile('A.txt', 'B.txt')){
  console.log("在這之間還能夠處理別的事情");
} ;  
console.log("Finished");   // 這行程序將在一小時後執行
console.log("Hello World, 整個程序已加載完畢,請享用"); // 這行程序將在一小時後執行

一個非阻塞式的函數,給你的編程帶來了更多的便利,你能夠在長IO操做的同時,寫點其餘的程序,提升效率。執行結果以下

start copying ... 在這之間還能夠處理別的事情 在這之間還能夠處理別的事情 在這之間還能夠處理別的事情 ... Finished Hello World, 整個程序已加載完畢,請享用

2.3 js中的異步非阻塞

咱們看到,一個非阻塞式的函數能給咱們編程帶來許多靈活性,咱們喜歡非阻塞式的函數。 
可是,又能夠看到同步的程序須要在一個循環中輪詢結果,循環裏面的程序會被執行好多遍,因此並很差控制來寫一些正常的程序,很難再利用起來。 
因此咱們須要一種更爲合理的方式對非阻塞式的函數進行利用。 
也就是我不會主動地去詢問結果,而是當你有告終果的時候再來通知我。 
// 這是一個非阻塞式函數 
// 若是複製已完成,則返回 true, 若是未完成則返回 false

//非阻塞式的有異步通知能力的函數
//如下不須要看懂,只用知道這個函數會在完成copy操做以後,執行success
function copyBigFile(afile,bfile, callback){
    var copying = copyFileAsync(afile, bfile, function(){ callback();});
    var isFinished = !copying;
    return !isFinished; 
}

這個函數不一樣於上一個同步非阻塞函數的地方在於,它具備通知功能,也就是說,它可以在完成操做以後主動地通知程序,「我完成了」。因而有程序以下,

console.log("start copying ... ");    
copyBigFile("A.txt","B.txt", function(){
          console.log("Finished");   //一個小時後被執行
          console.log("Hello World, 整個程序已加載完畢,請享用"); //一個小時後被執行
          })
console.log("幹別的事情"); 
console.log("作一些別的處理"); 

程序在調用copyBigFile函數以後,能夠當即得到返回值,線程沒有被阻塞住,因而還能夠去幹些別的事情,而後當copyBigFile完成以後,會執行指定的函數。因此程序的輸出應爲,

start copying ...
幹別的事情
作一些別的處理
Finished
Hello World, 整個程序已加載完畢,請享用

在這種狀況下,程序更容易控制,流程更爲清晰。一些「別的事情」能夠在函數還未通知以前進行處理,充分地提升了線程的利用效率。

相關文章
相關標籤/搜索