事件队列的基本原理
```
//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之后