一、前言
业务中遇到一个需求,所有修改操作都需要同步完成,即完成上一个请求之后才能发送下一个请求,当时没有找到好的方案,暂时用以下方式封装请求方法。哪位大佬有更好的实现方式可以放在评论区哦😯
二、实现
export interface IResponseData {
code: number;
zpData: any;
message: string;
}
type IJob = {
getParams: (...args: any[]) => any;
fn: (...args: any[]) => Promise<any>;
cb?: (...args: any[]) => void;
// 如果你的参数和执行时的状态无关,则可以用 params ,否则请用getParams(如,参数中包含请求时的时间or version等动态的参数时)
params?: any;
};
// 资源
const requestQueue: IJob[] = [];
let dealMachine = "idle";
const resolveQueue: any[] = [];
const rejectQueue: any[] = [];
export function queueRequest(job: IJob): Promise<IResponseData> {
requestQueue.push(job);
// 如果处理机空闲,继续执行下一个任务
if (dealMachine == "idle") {
requestPop();
}
return new Promise((resolve, reject) => {
resolveQueue.push(resolve);
rejectQueue.push(reject);
});
}
function requestPop() {
const job = requestQueue.shift();
if (job) {
// 如果有job,处理机处于 busy 状态
dealMachine = "busy";
job
.fn(job.params || job.getParams())
.then(res => {
job.cb && job.cb(res);
const resolve = resolveQueue.shift();
if (resolve) {
resolve(res);
}
})
.catch(error => {
const reject = rejectQueue.shift();
if (reject) {
reject(error);
}
})
.finally(() => {
// 执行完成,处理机处于 idle 状态
dealMachine = "idle";
requestPop();
});
}
}
三、例子
functin savePosition() {
const res = await queueRequest({
fn: _saveItemPosition,
getParams: () => ({
paletteId: route.params.paletteId, // 画板id
itemPositionList,
version: versionManager.version, // 版本号
}),
});
if (res.code == 0) {
} else {
}
}