(
key: string,
callback: CB
)
| 133 | |
| 134 | // 事务处理,如果有事务正在进行,则等待 |
| 135 | public tx<T, CB extends (val: T | undefined, tx: { set: (newVal: T) => void; del: () => void }) => any>( |
| 136 | key: string, |
| 137 | callback: CB |
| 138 | ): Promise<Awaited<ReturnType<CB>>> { |
| 139 | const enum Actions { |
| 140 | NONE = 0, |
| 141 | SET = 1, |
| 142 | DEL = 2, |
| 143 | } |
| 144 | return stackAsyncTask(key, () => { |
| 145 | let ret: Awaited<ReturnType<CB>>; |
| 146 | const act = { action: Actions.NONE } as { action?: number; newVal?: T }; |
| 147 | const set = (newVal: T) => { |
| 148 | act.action = Actions.SET; |
| 149 | act.newVal = newVal; |
| 150 | }; |
| 151 | const del = () => { |
| 152 | act.action = Actions.DEL; |
| 153 | act.newVal = undefined; |
| 154 | }; |
| 155 | return this.get<T>(key) |
| 156 | .then((result) => { |
| 157 | const tx = { |
| 158 | set, |
| 159 | del, |
| 160 | }; |
| 161 | return callback(result, tx); |
| 162 | }) |
| 163 | .then((result) => { |
| 164 | ret = result; |
| 165 | if (act.action === Actions.SET) { |
| 166 | return this.set(key, act.newVal); |
| 167 | } else if (act.action === Actions.DEL) { |
| 168 | return this.del(key); |
| 169 | } |
| 170 | }) |
| 171 | .then(() => ret); |
| 172 | }); |
| 173 | } |
| 174 | |
| 175 | incr(key: string, increase: number): Promise<number> { |
| 176 | return this.tx(key, (value: number | undefined, tx) => { |
no test coverage detected