Closed fangmd closed 3 years ago
第二部分 异步和性能
console.*
实际上是异步执行的JS引擎本身没有异步概念,需要外部的 事件调度 工具实现异步功能。
setTimeout(...)
是在一定时间后,把事件加入到事件队列中,等待执行。
程序被分成很多个小块,小块在事件队列中等待执行。
用户交互、IO、定时器会向事件队列中加入事件。
非交互:多个事件,事件的处理顺序不会影响结果
交互:多个事件,事件的处理顺序影响最终结果
协作:JS 单线程,如果出现大量的JS代码执行会让页面卡顿,可以通过事件循环机制让一部分任务延后处理,让引擎先处理UI代码
var res = [];
// response(..)从Ajax调用中取得结果数组
function response(data) {
// 一次处理1000个
var chunk = data.splice( 0, 1000 );
// 添加到已有的res组
res = res.concat(
// 创建一个新的数组把chunk中所有值加倍
chunk.map( function(val){
return val * 2;
})
);
// 还有剩下的需要处理吗?
if (data.length > 0) {
// 异步调度下一次批处理
setTimeout( function(){
response( data );
}, 0 );
}
}
// ajax(..)是某个库中提供的某个Ajax函数
ajax( "http://some.url.1", response );
ajax( "http://some.url.2", response );
ES6中, 在事件队列(tick)的基础上增加一个 任务队列(微任务队列)。
每个 tick 必须处理完所有的 微任务队列中的事件。
JS 编译器在编译 JS 代码的时候会做优化,对语句重新排序。有些是安全排序,有些是危险排序。
在喜欢一系列异步任务按顺序处理的时候,就会出现回调地狱。
回调导致业务处理逻辑复杂
回调是控制反转的,我们无法确定回调函数会返回什么样的数据,所以需要对回调函数的参数做校验。
回调去表达程序异步和管理并发的两个主要缺陷:缺乏顺序性和可信任性。
Promise 解决的问题:
1. 地狱式回调
2. 回调执行次数过多或过少。then 只会被执行一次
3. 吞掉错误或异常。catch 会处理异常
4. 逻辑流,链式调用
Promise.all([..])
: 同时执行多个 Promise 任务,并同时获得两个结果。
Promise.race([...])
:同时执行多个 Promise 任务,取第一个结果。借助这个功能可以实现一个超时竞赛的功能):
// 为foo()设定超时
Promise.race( [
foo(), // 启动foo()
timeoutPromise( 3000 ) // 给它3秒钟
])
.then(
function(){
// foo(..)按时完成!
},
function(err){
// 要么foo()被拒绝,要么只是没能够按时完成, // 因此要查看err了解具体原因
} );
单一值:对于需要返回多个值的情况不适合
无法取消
性能:Promise 相比较 回调 来说要执行的步骤更多
不看了,不用上
JS 实现多线程执行。
Web Worker 与主程序直接不会共享任何作用域或资源,没有多线程需要处理的并发问题。
Web Worker 与主程序通过事件监听方式做交互。
如何测试某个运算的速度?
方式1:运行前后记录时间,得到时间差。
局限性:对于ms以下量级的运算不适合;只能计算一次的时间,不能代表大多数情况;
重复执行取平均值:
后续没看,用不上
blog
第一部分 类型和语法
类型
null, undefined, boolean, number, string, object, symbol(ES6 新增)
值
JS 数字类型基于 IEEE 754 标准实现,“浮点数”。JS 使用双精度格式 (64位二进制)
NaN
NaN 与自身不相等
可以使用
Number.isNaN(...)
判断一个数是否是NaN
无穷数
Infinity, -Infinity
值和引用
简单值就是传值,复合值(对象)就是传引用
数组浅拷贝:
var b = a.slice()
封装的基本类型值对象(Number String ...),还是传的值。
原生函数
String(), Number(), Boolean(), Array(), Object(), Function(), RegExp(), Date(), Error(), Symbol()
Class
查看
Class
属性:拆封:
xx.valueOf()
强制类型转换
分为:隐式强制类型转换,显式强制类型转换
toString(), toNumber()
parseInt(..), parseFloat(..)
!!xxx
字符串和数字直接的隐私转换:
宽松相等和严格相等: 宽松相等允许进行强制类型转换,严格相等不允许强制类型转换
语法
语句都有结果值,在控制台直接执行语句可以看到结果值(undefined 或者 其他)
TypeError, ReferenceError, SyntaxError