事件隊列的基本原理
```
//eventLoop ->事件隊列,由外部push
var eventLoop = [];
var event
while(true) {
//一次tick
if(eventLoop.length > 0) {
event = eventLoop.shift();
try { event() }
catch(err) { reportError(err); }
}
}
```
javascript是單線程的,函數具有原子性,一旦foo或bar開始運行,bar或foo的任意一行代碼都必須在前一個函數執行后才會執行,也就是說異步的結果只有兩種可能
```
a = 1, b = 2;
foo = () => {a++; b = a + b;}
bar = () => {a--; b = a - b}
ajax(url, foo)
ajax(url, bar)
```
onscroll事件發送ajax請求并處理響應,js是單線程,一次只能一個事件,要么是onscroll執行發送請求,要么是處理請求
```
onscroll,請求1
onscroll,請求2
響應1
onscroll,請求3
響應2
響應3
```
如果結果值依賴于兩個請求的結果,可以這樣
```
var res = [];
function responese(data) {
if(data.name = 'qc') res[0] = data;
else if(data.name = 'sunny') res[1] = data;
}
//假設aurl返回data的name為qc,burl為sunny
ajax('aurl', response);
ajax('burl', response);
//這樣一來,無論誰先返回請求,res的結果都不受影響
```
```
var a, b;
function foo(x) { a = x * 2; baz();}
function bar(y) {b = y * 2; baz();}
function baz() {console.log(a + b);}
ajax('aurl', foo);
ajax('burl', bar);
//無論誰先返回請求,baz在執行console時都會報錯,因此此時要么沒有a要么沒有b
function foo(x) { a = x * 2; a && b && baz();}
function bar(y) {b = y * 2; a && b && baz();}
//先返回請求的一定不會執行baz,但此時的a或b已經賦值成功,后返回請求的一定執行baz
//我們稱a && b為門,只有a、b都準備好后,才把門打開(baz())
```
批處理
```
var res = [];
function response(data) {
res = res.concat(data.map(val => val * 2));
}
ajax('aulr', response);
ajax('bulr', response);
//之前說了,一個函數在執行時另一個函數只能等待。假設a響應先返回,但a的數據量很大很大,那么b回來后只能等待a執行完后才執行,此時頁面上的其他代碼都不會執行
```
```
function response(data) {
//一次只處理1000個
var chunk = data.splice(0, 1000);
res = res.concat(chunk.map(val => val * 2));
//還有要處理的嗎
//利用setTimeout將剩下的放在事件隊列最后,保證另一個響應的函數先執行
//代價就是會產生很多的后續進程
if(data.length > 0) {setTimeout(() => response(data))}
}
```
- 你不知道的JS上
- 第一部分 第三章 函數作用域和塊作用域
- 第一部分 第四章 提升
- 第一部分 第五章 閉包
- 第二部分 第一章 關于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 對象
- 第二部分 第五章 原型
- 第二部分 第六章 行為委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函數
- 第一部分 第四章 強制類型轉換
- 第一部分 第五章 語法
- 第二部分 第一章 異步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 總結
- 第二部分 第二章 語法
- 第二部分 第三章 代碼組織
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元編程
- 第二部分 第八章 ES6之后