/// ----------w1-----w2-----------------
/// -----------------------C1---------C2
存在一个写缓冲区,可以在其中发出命令,一旦完成,就会调用与之关联的回调fn。
要求写命令应按顺序执行,例如如果执行了 w1 命令,然后在 w2 之后,一旦 w1 完成,就应执行 w2 。一旦完成, w1 和 w2 应调用它们各自的完成功能 C1 , C2 。
它使用RxJs实现,按照规范运行,但是有一些痛点。我没有使用回调,而是使用await使代码流线性化。
function atomicWrite$(time, cmd) {
return timer(time).pipe(
take(1),
tap(() => console.log('done cmd: ', cmd))
);
}
const commandList = [];
let signalNextWrite$ = new ReplaySubject(1);
async function monsterProcess$(index, time) {
console.log('entered loop', index);
await signalNextWrite$.pipe(filter(idx => index === idx), take(1)).toPromise();
console.log('processing start:', index, time);
await of(commandList[index]).pipe(
concatMap(cmd => atomicWrite$(time, cmd))
).toPromise();
console.log('processing end:', index, time);
signalNextWrite$.next(index + 1);
return EMPTY.toPromise();
}
function writeIssue(command, time) {
commandList.push(command);
return monsterProcess$(commandList.length - 1, time);
}
signalNextWrite$.next(0);
setTimeout(async () => {
const res = await writeIssue('windows xp2', 5000);
console.log('completed windows');
});
setTimeout(async () => {
const res = await writeIssue('mac siera', 1000);
console.log('completed mac');
});
问题不是signalNextWrite$
,而是像互斥锁那样的某个时间,它会等到锁解锁后再继续。
在这里,作为过滤器发出的命令的索引(idx)阻止了发出的其他写命令的执行。
想离开数组的索引作为锁定逻辑,而使用其他逻辑等待当前命令完成并发出完成信号。
也要避免使用此代码:
signalNextWrite$.next(0);
Stackblitz,例如https://stackblitz.com/edit/typescript-r45p2d