淺談JS三座大山之異步和單線程
單線程
但是我們在開發中,遇到請求網絡,或者定時任務的時候,如果等待網絡請求結束或者定時任務結束的時候再去做其他事情,這樣頁面就會卡住,所以js有異步機制解決這個問題。
異步
異步的特點是不會阻塞後面的代碼執行,當同步任務執行完畢之後,再執行異步任務。相對的,同步會阻止代碼執行。異步任務的應用主要有網絡請求和定時任務。
異步是通過callback的方式實現的,在callback裡面執行異步執行的代碼,但是有一些場景比如我們有三個網絡請求abc需要依次執行,在a的回調裡發起b請求,在b的回調裡發起c請求,這樣會造成一種很混亂的寫法,稱之為回調地獄,可以試想一下,如果頁面邏輯過於復雜,需要依次調用10個接口,那麼代碼的可讀性會非常非常差,我們如果看到瞭別人的這種代碼難免內心奔跑一萬隻神獸。
promise基本用法:
let fun1 = function(flag){ return new Promise((resolve,reject)=>{ if(flag){ setTimeout(() => { resolve("success") }, 1000); }else{ setTimeout(() => { reject("fail") }, 1000); } }) } fun1(true).then((res)=>{ console.log(res)//success }).catch((res)=>{ console.log(res) }) fun1(false).then((res)=>{ console.log(res) }).catch((res)=>{ console.log(res)//fail })
上面是一個最簡單的promise函數,promise函數返回一個Promise對象,參數是一個函數,接收兩個參數resolve和reject,這兩個參數也是函數,當執行resolve()或者reject()的時候,函數返回.
如果執行瞭resolve(),就會在調用的時候執行then()方法,並接收resove()返回的參數;
如果執行瞭reject(),就會在調用的時候執行catch()方法,並接收reject()返回的參數;
用promise重新實現一下上面三個網絡請求的問題:
let callService = function(url){ return new Promise((resolve,reject)=>{ axios.get(url).then((res)=>{ resolve(res) }).catch((err)=>{ reject(err) }) }) } const url1 = "/user/url1" const url2 = "/user/url2" const url3 = "/user/url3" callService(url1).then((res)=>{ // do something return callService(url2) }).then(()=>{ // do something return callService(url3) }).then((res)=>{ // do something }).catch((err)=>{ console.log(err) })
用上面的寫法重新實現之後,寫法上隻會有一層,而不會陷入層層的回調之中。
promise.all
promise.all可以將多個promise包裝成一個新的實例,成功的時候返回一個數組,誰先失敗返回誰的值。
promise.all方法可以幫我們處理日常開發中多接口同時調用的處理問題。
let p1 = new Promise((resolve, reject) => { resolve('成功瞭') }) let p2 = new Promise((resolve, reject) => { resolve('success') }) Promise.all([p1, p2]).then((result) => { console.log(result) //['成功瞭', 'success'] }).catch((error) => { console.log(error) })
promise.race
這個方法的作用是多個接口賽跑,哪個跑得快就返回哪個
Promise.race([p1, p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error) })
以上就是淺談JS三座大山之異步和單線程的詳細內容,更多關於JS三座大山之異步和單線程的資料請關註WalkonNet其它相關文章!