JS事件流

事件流包括三个阶段:

  1. 事件捕获阶段
  2. 处于目标阶段
  3. 事件冒泡阶段

addEventListener(type, fn, false)
第一个参数:事件类型
第二个参数:事件函数
第三个参数:默认false表示使用冒泡机制,true表示捕获机制。

阻止冒泡:e.stopPropagation()

事件委托:
e.target 返回触发事件的元素,不一定是绑定事件的元素
e.currentTarget 返回的是绑定事件的元素($div.addEventListener),返回的就是$div

CommonJS、AMD、UMD

  1. CommonJS: 实现编译代码,创建一个比原先更大的代码包,其中包含了所有应用运行所需的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const axios = require('axios')
const fs = require('fs')

const moduleA = function() {}
const moduleB = function() {}
const moduleC = function() {}

exports.moduleA = moduleA
exports.moduleB = moduleB
exports.moduleC = moduleC

module.exports = {
moduleA,
moduleB,
moduleC,
}

特点:
没有回调函数
同步加载,每个require语句会短暂阻塞代码的运行,知道模块加载完毕。不过这个加载不是通过网络加载,而是从内存或者文件系统中加载,所以这个过程很快。
代码简单易懂
CommonJS模块不适合浏览器,因为浏览器的加载机制不支持同步。需要用打包工具把所有CommonJS模块打包成一个js文件。

  1. AMD:Asynchronous Module Definition(异步模块规范),用异步加载技术来定义模块和依赖。提供define方法和require方法来定义和加载模块。
    工厂函数内部包含了模块代码,工厂函数最后返回的结果,就是要暴露给其他模块的功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// define方法
define(
'模块id',
['依赖数组'],
function(['依赖数组']){ //工厂函数
// ...
}
);

// require方法
require(['jquery'],
function($){ //回调函数
...
}
);

define方法特点:
用AMD定义的模块至少需要一个工厂函数来暴露API给其他模块使用。
依赖数组中的依赖会被异步加载。
模块的加载通过客户端(浏览器)向服务器发送HTTP请求来完成的,这个传输过程需要大量时间。
可以定义具名模块,也可以定义匿名模块。具名模块通过开发者定义的名字加载,匿名模块隐式的以文件名加载。

require方法特点:
可以在代码的任何地方使用require加载另一个模块。
require调用会发送一个请求来下载模块。
异步加载,只有在回调函数里才能获取新拿到的API。

  1. UMD:Universal Module Definition(通用模块规范)是由社区想出来的一种整合了CommonJS和AMD两个模块定义规范的方法。

基本原理:用一个工厂函数来统一不同的模块定义规范。

原则:
所有定义模块的方法需要单独传入依赖
所有定义模块的方法都需要返回一个对象,供其他模块使用

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(function (global, factory) {
if (typeof exports === 'object' && typeof module !== undefined) { //检查CommonJS是否可用
module.exports = factory(require('jquery'));
} else if (typeof define === 'function' && define.amd) { //检查AMD是否可用
define('toggler', ['jquery', factory])
} else { //两种都不能用,把模块添加到JavaScript的全局命名空间中。
global.toggler = factory(global, factory);
}
})(this, function ($) {
function init() {

}
return {
init: init
}
});

限制请求并发数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function multiRequest(urls = [], maxNum) {
// 请求总数量
const len = urls.length;
// 根据请求数量创建一个数组来保存请求的结果
const result = new Array(len).fill(false);
// 当前完成的数量
let count = 0;

return new Promise((resolve, reject) => {
// 请求maxNum个
while (count < maxNum) {
next();
}
function next() {
let current = count++;
// 处理边界条件
if (current >= len) {
// 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
!result.includes(false) && resolve(result);
// console.log(result)
return;
}
const url = urls[current];
console.log(`开始 ${current}`, new Date().toLocaleString());
new Promise((resolve, reject)=>{
let timer = setTimeout(()=>{
resolve(url)
clearTimeout(timer)
timer = null
}, Math.random()*2000+1000)
}).then().finally((res)=>{
console.log(`结束 ${current}-${url}`, new Date().toLocaleString());
result[current] = url;
// 请求没有全部完成, 就递归
if (current < len) {
next();
}
})
}
});
}

let list = [1,2,3,4,5,6,7,8,9,10]
multiRequest(list, 6)

navigator.sendBeacon() 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器。
它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest)发送分析数据的一些问题。

语法:

1
2
navigator.sendBeacon(url);
navigator.sendBeacon(url, data);

参数:

url
url 参数表明 data 将要被发送到的网络地址。

data 可选
data 参数是将要发送的 ArrayBufferArrayBufferViewBlobDOMStringFormDataURLSearchParams 类型的数据。

返回值:
当用户代理成功把数据加入传输队列时,sendBeacon() 方法将会返回 true,否则返回 false。

参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
https://blog.csdn.net/hsl0530hsl/article/details/88579958

TextDecoder

TextDecoder 接口表示一个文本解码器,一个解码器只支持一种特定文本编码,例如 utf-8、iso-8859-2、koi8、cp1261,gbk 等等。解码器将字节流作为输入,并提供代码点流作为输出。
在浏览器 WebAssembly 中,使用 TextDecoder 读取 WebAssembly 的二进制字节码文件。

参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/TextDecoder
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly

欢迎留言,提问 ^_^