1、迭代器模式
1、介绍
2、使用
- 结果
- 如何将
这三个方法 封装到一起 作为一个迭代器的方式 ?
3、UML 类图
- 代码实现
class Iterator {
constructor(container) {
this.list = container.list;
this.index = 0;
}
Next() {
// 如果下一项存在 index++
if (this.hasNext()) {
return this.list[this.index++];
}
return null;
}
hasNext() {
// 超出数组长度遍历到头了 返回 false
if (this.index >= this.list.length) {
return false;
}
return true;
}
}
class Container {
constructor(list) {
this.list = list;
}
// 生成遍历器 并将 container(this) 传入
getIterator() {
return new Iterator(this);
}
}
// 测试代码
let arr = [1, 2, 3, 4, 5];
const container = new Container(arr);
const iterator = container.getIterator();
while (iterator.hasNext()) {
console.log(iterator.Next());
}
- 结果展示
-
分明使用 Array.forEach 可解 为啥需要使用 这个 ? -
因为 之后会写兼容 所有有序的集合 非常强大
4、应用场景
- 代码展示
function each(data) {
// 生成遍历器
let iterator = data[Symbol.iterator]();
let item = { done: false };
while (!item.done) {
item = iterator.next();
if (!iterator.done) {
console.log(item.value);
}
}
}
// 测试
const arr = [1, 2, 3, 4, 5];
const nodeList = document.getElementsByTagName("p");
const m = new Map();
m.set("a", 100);
m.set("b", 200);
each(arr);
each(nodeList);
each(m);
- 结果展示
能否简化?
2、状态模式
1、介绍
- 代码展示
// 状态 控制 红灯 红灯 绿灯
class State {
constructor(color) {
this.color = color;
}
// context 是 Context 的一个实例
handle(context) {
console.log(`turn to ${this.color} light`);
// 设置状态
context.setState(this);
}
}
// 主体部分
class Context {
constructor() {
this.state = null;
}
// 获取状态
getState() {
return this.state;
}
setState(state) {
this.state = state;
}
}
// 测试
const context = new Context();
const green = new State("green");
const yellow = new State("yellow");
const red = new State("red");
// 绿灯亮了
green.handle(context);
console.log(context.getState());
// 黄灯亮了
yellow.handle(context);
console.log(context.getState());
// 红灯亮了
red.handle(context);
console.log(context.getState());
- 结果展示
2、场景 展示
1、有限状态机
-
代码展示
-
要先安装 yarn add javascript-state-machine --save
-
为了方便 安装 yarn add jquery --save
-
index.html 中需要一个 button id="btn1"
import StateMachine from "javascript-state-machine";
import $ from "jquery";
// 定义状态机
let fsm = new StateMachine({
init: "收藏",
transitions: [
{
name: "doStore",
form: "收藏",
to: "取消收藏",
},
{
name: "deleteStore",
form: "取消收藏",
to: "收藏",
},
],
methods: {
// 监听执行收藏
onDoStore: function () {
alert("收藏成功"); // 实际业务中此处 可发 post 请求
updateText();
},
// 监听执行收藏
onDeleteStore: function () {
alert("取消收藏成功"); // 实际业务中此处 可发 post 请求
updateText();
},
},
});
let $btn = $("#btn1");
//按钮点击事件
$btn.click(function () {
if (fsm.is("收藏")) {
fsm.doStore();
} else {
fsm.deleteStore();
}
});
// 更新 文案
function updateText() {
$btn.text(fsm.state);
}
// 初始化文案
updateText();
- 结果展示
成功实现状态 改变 非常 nice 非常好 !
2、写一个 promise
代码展示 (这个有点多 不过不困难)
import StateMachine from "javascript-state-machine";
// 状态机模型
let fsm = new StateMachine({
init: "pending", // 初始化状态
transitions: [
// 两个转变的状态
{
name: "resolve", // 事件名称
from: "pending",
to: "fullfilled",
},
{
name: "reject", // 事件名称
from: "pending",
to: "rejected",
},
],
methods: {
// 监听 resolve
onResolve: function (state, data) {
// state 当前状态机实例 data fsm.resolve(xxx)传递的参数
data.successList.forEach((fn) => fn());
},
onReject: function (state, data) {
// state 当前状态机实例 data fsm.reject(xxx)传递的参数
data.failList.forEach((fn) => fn());
},
},
});
// 写 promise
class MyPromise {
constructor(fn) {
this.successList = [];
this.failList = [];
fn(
function () {
// 调用状态机内的 resolve 实现状态变化
fsm.resolve(this);
},
function () {
// 调用状态机内的 reject 实现状态变化
fsm.reject(this);
}
);
}
then(successFn, failFn) {
this.successList.push(successFn);
this.failList.push(failFn);
}
}
// 测试代码 由这个熟悉的测试代码 实现promise
function loadImg(src) {
const promise = new MyPromise(function (resolve, reject) {
let img = document.createElement("img");
img.inload = function () {
resolve(img);
};
img.onerror = function () {
reject();
};
img.src = src;
});
return promise;
}
let src = "xxx";
let result = loadImg(src);
result.then(
function () {
console.log("ok1");
},
function () {
console.log("fail1");
}
);
result.then(
function () {
console.log("ok2");
},
function () {
console.log("fail2");
}
);
- 结果展示