编程与类型系统06
发表于:2024-07-01 | 分类: 学习

函数类型高级应用

装饰器模式

装饰器模式是一个简单的行为软件设计模式,可扩展对象的行为,而不必修改对象的类。装饰的对象可以执行其原始实现没有提供的功能。

class 装饰器:

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
class Widget {}

interface IWidgetFactory {
makeWidget(): Widget;
}

class WidgetFactory implements IWidgetFactory {
public makeWidget(): Widget {
return new Widget();
}
}
class SingletonDecorator implements IWidgetFactory {
private factory: IWidgetFactory;
private instance: Widget | undefined = undefined;

constructor(factory: IWidgetFactory) {
this.factory = factory;
}
public makeWidget(): Widget {
if (this.instance === undefined) {
this.instance = this.factory.makeWidget();
}
return this.instance;
}
}

函数装饰器:

1
2
3
4
5
6
7
8
9
10
11
12
class Widget {}

type IWidgetFactory = () => Widget;
function makeWidget(): Widget {
return new Widget();
}
function useWidgets(factory: IWidgetFactory) {
for (let i = 0; i < 10; i++) {
let widget = factory();
}
}

闭包

闭包和 lambda 捕获:lambda 捕获是 lambda 内捕获的一个外部变量。编程语言通过闭包来实现 lambda 捕获。闭包不只是一个简单的函数,它还记录了创建该函数时的环境,所以可以在不同调用之间维护状态。

可恢复的函数

可恢复的函数是跟踪自己状态的函数,在被调用时,不会从头运行,而是从上一次返回时所在的状态恢复执行。

异步执行

异步执行模型

线程

每个应用程序作为进程运行。进程在主线程上启动,但是我们可以创建其他多个线程来运行代码。

事件循环

事件循环使用一个队列:异步函数将被加入队列,而它们自己也可以将其他函数排队。只要队列不为空,队列中的第一个函数就将被取出来执行。

线程可以在多个 CPU 核心上并行运行,这是它们的主要优势。因为不同代码能够同时运行,所以整个程序能够更快地完成操作。其缺点在于进行同步的开销:在线程之间传递数据需要小心同步。

事件循环在单个线程上运行,但是能够在运行时间长的代码等待输入时,将其放到队列末尾。使用事件循环的优点是不需要同步,因为所有代码在一个线程上运行。缺点在于,虽然在 I/O 操作等待数据时让它们排队的效果很好,但是 CPU 密集的操作仍然会造成阻塞。

简化异步代码

promise 和 continuation:

promise 是将来某个时刻可用的值的一个代理。在生成该值的代码运行之前,其他代码可以使用该 promise 设置在该值可用后如何处理该值,在发生错误时如何处理,甚至取消将来的执行。在 promise 的结果可用后调用的函数称为 continuation。

关于 promise

处理错误

promise 可以处于三种状态之一:等待(pending)、完成(settled)和拒绝(rejected)。等待的意思是 promise 已被创建,但还没有完成(即提供的负责生成值的函数还没有调用 resolve())。完成的意思是已经调用了 resolve(),并提供了一个值,此时将调用 continuation。但是,如果存在错误,将发生什么?当负责提供值的函数抛出一个异常时,promise 将进入拒绝状态。

上一篇:
编程与类型系统07
下一篇:
编程与类型系统05