前端研發人員不要忘記了瀏覽器是安裝在PC電腦(手機)上的應用。既然是客戶端應用,就免不了一個問題:線程和進程。html
好,知道了這些基本的知識,咱們來看一下瀏覽器(以谷歌瀏覽器爲例)這個最基本的應用程序有哪些進程,又有哪些線程。
Chrome的進程:你們能夠打開任務管理器看看,有哪些進程
從圖中能夠看到,在chrome中每打開一個標籤頁,每個擴展程序都是一個進程。
Chrome的線程:對於一個進程來講,又有哪些線程呢?前端
那麼當你打開一個頁面,就啓動了一個進程,那麼這個進程有上面幾個線程。這幾個線程之間相互合做,可是GUI和JavaScript之間是相互獨立的,並且Javascript是單線程的。緣由很簡單,涉及UI操做的不能同時處理,否則給用戶呈現的頁面會是什麼樣子。
既然知道了,瀏覽器做爲應用程序具有的基本要素。那麼咱們想看看瀏覽器內部具體的工做方式。
瞭解一個程序,首先了解程序的模塊劃分和工做流程。
瀏覽器主要劃分這幾個模塊瀏覽器部件:那麼這幾個部件相互耦合,爲用戶提供頁面。html5
咱們重點來看一下瀏覽器的渲染是怎麼操做的
異步並非不執行,而是執行放入隊列。node
//案例一: setTimeout(() => { console.log(promise); console.log('settimeout1'); }, 0); let promise = new Promise(function(resolve, reject) { console.log('Promise'); setTimeout(()=>{ resolve('success'); },0); //resolve('success'); }).then((msg)=>{ console.log('resolved.'+msg); }); setTimeout(() => { console.log(promise); console.log('settimeout2'); }, 0); console.log(promise); console.log('Hi!'); //輸出結果 Promise //Promise會當即執行 Promise { <pending> } //此時promise狀態爲pending Hi! //打印hi Promise { <pending> } settimeout1 //主線程執行完畢,依次將三個settimeout放入macro隊列中,打印第一個 Promise { <pending> } settimeout2 //打印第二個 resolved.success //promise執行成功 //案例二: 若是promise中直接resolve('success'),運行結果是怎麼樣? Promise Promise { <pending> } Hi! resolved.success Promise { undefined } settimeout1 Promise { undefined } settimeout2 //案例三: 若是在React中的事件系統是什麼樣子的呢? class Father extends Component { render() { let promise = new Promise(function(resolve, reject) { resolve('success1'); }).then((msg)=>{ console.log('resolved.'+msg); }); return ( <Son ref="son"/> ); } componentDidMount(){ console.log('Did Mount'); } componentWillMount(){ let promise = new Promise(function(resolve, reject) { resolve('success2'); }).then((msg)=>{ console.log('resolved.'+msg); }); console.log('Will Mount'); } } //輸出結果 Will Mount Did Mount resolved.success2 resolved.success1 能夠看到react並無將micro任務合併到渲染裏面
爲何會說起React,由於React 的處理方式和咱們和瀏覽器的實現流程比較相似。
React初始化《======》瀏覽器初始加載
React更新 《======》瀏覽器的事件系統
因此React從很大程度上作了一層抽象,讓咱們面向組件的函數編程,而不是面向瀏覽器的編程。react
node環境中的事件系統多了兩個 process.nextTick和setImmediateweb
//案例四: setTimeout(() => { console.log(promise); console.log('settimeout1'); }, 0); let promise = new Promise(function(resolve, reject) { console.log('Promise'); /*setTimeout(()=>{ resolve('success'); },0);*/ resolve('success'); }).then((msg)=>{ console.log('resolved.'+msg); }); setTimeout(() => { console.log(promise); console.log('settimeout2'); }, 0); console.log(promise); console.log('Hi!'); process.nextTick(()=>{console.log('nextTick')}); setImmediate(()=>{console.log('Immediate')}) ; //輸出結果 Promise Promise { <pending> } Hi! nextTick resolved.success Promise { undefined } settimeout1 Promise { undefined } settimeout2 Immediate