题目
一个页面在交易确认弹窗还未关闭时又触发了签名请求,用户看到两个互相打断的弹窗;另一个页面在用户连点时,第二次请求直接失败。请说明并发钱包请求应该怎样设计,以及 -32002 这类响应应该如何处理。
考察目标
- request 的 Promise 语义与错误分流。
- 并发请求的产品与技术边界。
- 队列、取消与超时语义的设计。
用 Promise 语义与错误码分流处理重复请求,用队列保证同一时间只有一个待处理请求。
一个页面在交易确认弹窗还未关闭时又触发了签名请求,用户看到两个互相打断的弹窗;另一个页面在用户连点时,第二次请求直接失败。请说明并发钱包请求应该怎样设计,以及 -32002 这类响应应该如何处理。
按 EIP-1193,request 成功时 resolve 该方法的结果,失败时以带 code 的错误对象 reject;EIP-1474 的错误码表中 -32002 对应 Resource unavailable。也就是说,并发或重复请求的失败可以通过错误码分流,但具体在什么条件下由钱包返回 -32002,属于钱包实现差异。因此并发请求的设计需要把错误码分流与钱包行为差异一起考虑。实现差异与工程取舍见深入回答。
// 串行化钱包请求的最小示例:同一时间只允许一个待用户处理的请求。
let tail: Promise<unknown> = Promise.resolve();
export function enqueueWalletRequest<T>(task: () => Promise<T>): Promise<T> {
const run = tail.then(
() => task(),
() => task(),
);
// 吞掉前一个请求的失败,保证队列继续推进。
tail = run.catch(() => undefined);
return run;
}
示例省略了超时、取消与状态提示。
发现这道题有问题? 反馈此题