空闲时使用函数式编程可达到 60fps
自发布以来, js-coroutines已经能够处理诸如解析和字符串化 JSON 或压缩空闲数据之类的标准函数,并将任务拆分到多个帧中,从而使所有内容都能以 60fps 的流畅度运行——现在它也具备了构建函数式管道的能力:
const process =
pipe(
parseAsync,
mapAsync.with((v) => ({...v, total: v.units * v.price})),
stringifyAsync,
compressAsync
)
这是一个虚拟例程,它解析一些 JSON,计算出项目的总值,将其存储回 JSON,并对其进行压缩。
然后我们就可以用我们的数据调用这个管道了:
const compressedData = await process(inputJSON)
该函数创建了一个异步进程,该进程与标准的js 协程pipe结合使用,在主线程上协同运行所有作业,从而确保有足够的时间进行动画和交互。
我们也可以插入自己想要拆分的计算:
const process = pipe(
parseAsync,
function * (data) {
let i = 0
let output = []
for(let item of data) {
output.push({...item,
total: item.units * item.price,
score: complexScore(item)
})
if((i++ % 100)==0) yield
}
return output
},
tap(console.log),
stringifyAsync
)
这里我们将一个生成器函数放入流水线,并确保yield时不时地调用它。这个 yield 调用会检查我们是否有足够的时间继续执行,或者安排在下一个空闲时间恢复执行该函数。
新功能
| 功能 | 参数 | 目的 |
|---|---|---|
pipe |
...function
每个函数可以是异步函数、普通函数或生成器。 该函数接收管道的当前值并对其进行处理。您可以使用该 |
创建一个异步函数来执行管道 |
tap |
function(current){...} |
此函数会向管道添加一个函数,该函数接收当前值,但不返回结果。您可以使用它来实现诸如日志记录或保存之类的副作用。管道会暂停执行,直到该函数执行完毕。 |
branch |
function(current){...} |
此函数向管道添加一个接收当前值的函数。您可以使用它来实现诸如日志记录或保存之类的副作用。管道不会暂停执行,因此会从此点开始形成一个新的延续。 |
repeat |
function,times |
创建一个函数,该函数执行指定的函数次数。 |
call |
function,...params |
此函数允许调用另一个函数,该函数将接受管道的当前值,但需要额外的参数。提供的参数将附加到管道的当前值之后。 |
